1

Trying to make a Nextjs app with apollo, graphql and prisma. When I'm trying to query users on my front end, I'm getting a 400 error. The query works in apollo studio / sandbox so I have no idea how to fix it.

error.message: Response not successful: Received status code 400 And nothing in the server log.

schema.ts:

export const  typeDefs = gql`
    type User {
        id: String
        name: String
        email: String
        image: String
    }

    type Query {
        AllUsersQuery: [User]!
    }

my resolver.ts:

export const resolvers = {
    Query: {
        AllUsersQuery: async (_parent: any, __args: any, context: any) => await context.prisma.user.findMany(),
    },
};

And where I'm calling it from board.tsx:


const AllUsersQuery = gql`
  query {
      user{
        id
        name
        email
      }
  }
`

const Board = () => {
  const { data, loading, error } = useQuery(AllUsersQuery);

  if (loading) return <div> Loading... </div>
  if (error) return <div> Oops something went wrong: {error.message}</div>

  return (
    <>
      <div>{data?.user.email}</div>
    </>
  )
}

export default Board

response/request header:

XHRPOSThttp://localhost:3000/api/graphql
[HTTP/1.1 400 Bad Request 13ms]

    
POST
    http://localhost:3000/api/graphql
Status
400
Bad Request
VersionHTTP/1.1
Transferred766 B (1.21 kB size)
Referrer Policystrict-origin-when-cross-origin

        
    HTTP/1.1 400 Bad Request

    Access-Control-Allow-Origin: *

    Access-Control-Allow-Credentials: true

    Content-Type: application/json

    Vary: Accept-Encoding

    Content-Encoding: gzip

    Date: Sun, 02 Oct 2022 03:20:09 GMT

    Connection: keep-alive

    Keep-Alive: timeout=5

    Transfer-Encoding: chunked
        
    POST /api/graphql HTTP/1.1

    Host: localhost:3000

    User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0

    Accept: */*

    Accept-Language: en-CA,en-US;q=0.7,en;q=0.3

    Accept-Encoding: gzip, deflate, br

    Referer: http://localhost:3000/board

    content-type: application/json

    Content-Length: 91

    Origin: http://localhost:3000

    Connection: keep-alive

    Cookie: _ga=GA1.1.1971964746.1663710154; next-auth.csrf-token=33c501d5216dea4b6a029d34c13d640814228810867843882008780ce09eb536%7C83d7939882d2f38e49f72a501e895459abb7fbac2fbab0d106c6462fe35cbe7e; next-auth.callback-url=http%3A%2F%2Flocalhost%3A3000%2Flogin; next-auth.session-token=c7358df1-2605-4a34-bb5d-a1091a00b871

    Sec-Fetch-Dest: empty

    Sec-Fetch-Mode: cors

    Sec-Fetch-Site: same-origin

What am I doing wrong? Thanks

1 Answer 1

2

It appears you need to clean and flip some naming conventions. You likely want to define a resolver on your root Query type simply as users, which in turn is the field you'll access on the returned optional (data) on execution. Defining the query in this way provides flexibility; for example perhaps you add a filter arg in the future with a simple id or more complex input type. In the case, the lack of flexibility becomes evident.

export const  typeDefs = gql`
    type User {
        id: String
        name: String
        email: String
        image: String
    }

    type Query {
       users: [User]!
    }

  // update resolver to reflect schema change on Query
  Query: {
       users: async (_parent: any, __args: any, context: any) => await context.prisma.user.findMany(),
    },


Now, for your (currently filterless) query operation it makes sense to declare AllUsersQuery, an accurate description of your client implementation. In the case you added an arg to fetch a subset (which would require updating resolver to something like users(ids: [String]): [User], a different naming convention could be provided for the operation (UsersByIdsQuery)

const AllUsersQuery = gql`
  query {
      users {
        id
        name
        email
      }
  }
`

const Board = () => {
  const { data, loading, error } = useQuery(AllUsersQuery);

  if (loading) return <div> Loading... </div>
  if (error) return <div> Oops something went wrong: {error.message}</div>

  return (
    <>
      <div>{data?.users.email}</div>
    </>
  )
}

export default Board

If you wanted to leave your schema, resolver, and operation as is, you would need to update the field requested on your query as reflected in your schema, and similarly access that field on the data optional in your code.

const AllUsersQuery = gql`
  query {
     AllUsersQuery {
        id
        name
        email
      }
  }
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks, I intend to add a query later that gets a single user by id. Would you happen to know why this query is not working though?
Yes, see updated response. You would need to update query doc to reflect your resolver name, which in turn would be the field accessed on returned data optional. That said, this syntax is probably not within scope of best practice. A compromise might be to change AllUsersQuery to allUsers (then update where this is used throughout)
Ahh thank you very much. I was following a tutorial with this naming convention, Is there a resource you would recommend for best practices?
Also maybe a resource for more relations between models?
will drop one in comment momentarily -- just to note if you opted to allUsers, the compromise noted above, you should define another resolver on Query for users which would accept a filter or id.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.