ApolloClient все значения приводят к нулю при выполнении мутации - PullRequest
1 голос
/ 12 июля 2020

Я начал использовать ApolloClient и должен сказать, что документация ужасна.

Мое приложение будет использовать GraphQL, но вход в систему должен выполняться с помощью простого запроса POST к /login с указанием имени пользователя и пароль, как данные формы.

И, черт возьми, заставить это работать было полным кошмаром.

Поскольку мне нужно использовать apollo-link-rest, мне нужно сначала создать своего клиента:

import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
import { createHttpLink } from 'apollo-link-http'
import { onError } from 'apollo-link-error'
import { RestLink } from 'apollo-link-rest'

const cache = new InMemoryCache()

const httpLink = new createHttpLink({
  credentials: 'include',
})

const restLink = new RestLink({
  endpoints: {
    localhost: {
      uri: "http://localhost:8080"
    }
  },
  credentials: 'include'
})

const errorLink = onError(({ graphQLErrors, networkError, operation }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ message, locations, path }) => {
      console.log(`[GraphQL error] Message: ${message}, ${path}`)
    })
  }
  if (networkError) {
    console.log(
      `[Network error ${networkError}] Operation: ${operation.operationName}`
    )
  }
})

export const client = new ApolloClient({
  link: ApolloLink.from([errorLink, restLink, httpLink]),
  cache,
})

тогда у меня есть мой запрос:

const LOGIN_QUERY = gql`
  mutation doLogin($username: String!, $password: String!, $formSerializer: any) {
    user(input: { username: $username, password: $password})
      @rest(
        path: "/login"
        type: "user"
        method: "POST"
        endpoint: "localhost"
        bodySerializer: $formSerializer
      ) {
        id
        name
      }
  }`

const formSerializer = (data, headers) => {
  const formData = new URLSearchParams()
  for (let key in data) {
    if (data.hasOwnProperty(key)) {
      formData.append(key, data[key])
    }
  }

  headers.set('Content-Type', 'application/x-www-form-urlencoded')

  return { body: formData, headers }
}

Я нахожу совершенно безумным, что в документации нет примера того, как вы отправляете данные формы, мне пришлось много гуглить, пока я выяснил, как это сделать.

и я выполняю запрос в компоненте входа:

  const [doLogin, { data }] = useMutation(LOGIN_QUERY, {
    onCompleted: () => {
      console.log("Success")
    },
    onError: () => {
      console.log("Poop")
    }
  })

  const handleSubmit = (event) => {
    event.preventDefault()
    console.log('logging in...')
    doLogin({
      variables: { username, password, formSerializer },
    })
  }

сервер регистрирует меня, возвращает приготовление сеанса ie и тело, содержащее :

{
    "data": {
        "user": {
            "id": 1
            "name": "Foobar"
        }
    }
}

Когда я проверяю состояние кеша с помощью плагина ApolloClient google chrome, в кеше есть:

user:null
    id: null
    name: null

, так что вот мои вопросы:

  1. Нужно ли мне устанавливать состояние по умолчанию?
  2. Только в документации мутации объектов, которые были запрошены в первую очередь, могу ли я обновить кеш, используя мутацию, только если объект уже существует в кеше?
  3. Нужно ли мне писать преобразователи для каждого типа?
  4. А из c, почему я получаю нулевые значения?
  5. Нужно ли возвращать все данные, завернутые в объект data, даже для запросов отдыха?
  6. Должен ли formSerializer быть переданным как переменная в запрос, потому что я считаю это супер уродливым.

Как уже было сказано ... документация ApolloClient - одна из худших документов, которые я когда-либо читал. Совершенно не удобен для пользователя.

1 Ответ

1 голос
/ 12 июля 2020

Согласно Преобразование ответа , apollo ожидает ответа от REST API, например, следующего:

{
  "id": 1,
  "name": "Apollo"
}

Если вы не можете управлять серверной частью, вы можете использовать настраиваемый преобразователь ответа:

responseTransformer: async response => response.json().then(({data}) => data.data?.user)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...