Попытка сделать приложение Nextjs с помощью apollo, graphql и prisma. Когда я пытаюсь запросить пользователей на своем внешнем интерфейсе, я получаю ошибку 400. Запрос работает в студии / песочнице Apollo, поэтому я понятия не имею, как его исправить.
сообщение об ошибке: Response not successful: Received status code 400
А в логе сервера ничего.
схема.тс:
export const typeDefs = gql`
type User {
id: String
name: String
email: String
image: String
}
type Query {
AllUsersQuery: [User]!
}
мой решатель.ts:
export const resolvers = {
Query: {
AllUsersQuery: async (_parent: any, __args: any, context: any) => await context.prisma.user.findMany(),
},
};
И где я вызываю его из 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
заголовок ответа/запроса:
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
Что я делаю не так? Спасибо
Похоже, вам нужно очистить и перевернуть некоторые соглашения об именах. Вероятно, вы захотите определить преобразователь для вашего корневого типа запроса просто как users
, который, в свою очередь, является полем, к которому вы будете обращаться в возвращаемом необязательном (data
) при выполнении. Такое определение запроса обеспечивает гибкость; например, возможно, в будущем вы добавите аргумент фильтра с простым id
или более сложным типом ввода. В случае отсутствия гибкости становится очевидным.
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(),
},
Теперь для вашей (в настоящее время нефильтрованной) операции запроса имеет смысл объявить AllUsersQuery
точное описание реализации вашего клиента. В случае, если вы добавили аргумент для получения подмножества (что потребует обновления распознавателя до чего-то вроде users(ids: [String]): [User]
, для операции может быть предусмотрено другое соглашение об именах (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
Если вы хотите оставить свою схему, преобразователь и операцию как есть, вам нужно будет обновить поле, запрошенное в вашем запросе, как это отражено в вашей схеме, и аналогичным образом получить доступ к этому полю в необязательных данных в вашем коде.
const AllUsersQuery = gql`
query {
AllUsersQuery {
id
name
email
}
}
Да, см. обновленный ответ. Вам нужно будет обновить документ запроса, чтобы отразить имя вашего распознавателя, которое, в свою очередь, будет необязательным полем, к которому обращаются возвращаемые данные. Тем не менее, этот синтаксис, вероятно, выходит за рамки передовой практики. Компромисс может состоять в том, чтобы изменить AllUsersQuery
на allUsers
(затем обновить, где это используется повсюду)
Ахх спасибо большое. Я следовал учебнику с этим соглашением об именах. Есть ли ресурс, который вы бы порекомендовали для лучших практик?
Также, может быть, ресурс для большего количества отношений между моделями?
на мгновение бросит один в комментарий - просто чтобы отметить, что если вы выбрали allUsers
, компромисс, отмеченный выше, вы должны определить другой преобразователь в Query для users
, который примет фильтр или идентификатор.
перечитал бы документацию на graphql.org, просмотрел документы ApolloServer, содержащие основы типов, схем и т. д., а затем обратился бы сюда: apollographql.com/docs/react/data/operation-best-practices. не могли бы вы уточнить, что вы подразумеваете под отношениями между моделями.
О, спасибо, я не заметил, что у них есть раздел с лучшими практиками. Я просматривал эти документы. Под отношениями я подразумеваю, например, объединение таблиц в SQL? У меня определена схема prisma, но я не знаю, как показать это в GraphQL. Или многие ко многим в схеме/резольверах.
Спасибо, я намерен позже добавить запрос, который получает одного пользователя по идентификатору. Вы случайно не знаете, почему этот запрос не работает?