Подумайте о том, как сделать хороший дизайн API с помощью GraphQL

задняя часть внешний интерфейс GraphQL

В настоящее время я пишу graphql уже больше года и часто думаю об отличии от Rest API и вдохновении для API Design.

Камни с других холмов, можно узнать. Некоторые естественные проекты или идеи qraphql имеют большое справочное или справочное значение для написания Rest API.

Вот краткое изложение некоторых вдохновленных руководств по дизайну API.

Если вы не знакомы с graphql, вы можете обратиться ккитайская документация graphql

Ссылка на эту статьюMountain.Specialty/post/API-of…

вернуть идентификатор для всех ресурсов

В graphql скалярный типIDИспользуется для представления глобальной уникальности ресурсов. существуетapollo-clientТакже рекомендуется, чтобы клиент приносил идентификатор с каждым запросом.

Добавление идентификатора в ответ имеет как минимум два преимущества.

  1. Кэширование ресурсов на стороне клиента
  2. Это полезно для отслеживания данных по всей ссылке от восходящего потока данных до клиента.

Поля для загрузки ресурсов по запросу

query TODO {
  todo (id: 10) {
    id 
    name
    status
  }
}

Если клиенту нужно только отобразить статус и имя TODO, ему нужно вернуть только поля имени и статуса, что значительно снижает сетевой трафик.

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

Чтобы получить поля, запрошенные запросом graphql, вам необходимо вручную разрешить информацию о четвертом поле функции GraphQLFieldResolveFn и настроить директиву для каждого поля, чтобы отметить связь между полем Graphql Filed и полем базы данных.

Дополнительные поля можно использовать для загрузки по запросу в Rest API.Если тег fields используется для возврата обязательных полей, если такого поля нет, то по умолчанию возвращаются все поля ресурса, а поля структурируются в промежуточном программном обеспечении.

// 请求 Todo:10,并且只需要 id,name,status 三个字符安
'/api/todos/10?fields=id,name,status'

// 请求 Todo:10 全部资源
'/api/todos/10'

Связанные ресурсы представлены с помощью вложенных объектов

Этот запрос представляет собой список пользователей, каждому из которых необходимо отобразить имя последнего Todo. Todo необходимо представлять с помощью вложенных объектов.

query USERS {
  users {
    id
    name
    lastTodo {
      id
      name
    }
  }
}

В дизайне Rest API часто видно, что все данные расширяются, что не только не позволяет найти ресурсы, но и затрудняет расширение данных. Вложенные данные могут гибко расширять данные, а также могут загружать вложенные данные по запросу.

const res0 = {
  users: [{
    id: 1,
    name: "山月",
    todoName: "学习"
  }]
}

// 修改后
const todoFields = {}
const res = {
  users: [{
    id: 1,
    name: "山月",
    todo: {
      id: 1,
      name: "学习",
      ...fields
    }
  }]
}

// 可以这样设计 API
const api = '/api/users?fields=id,name,todo.id,todo.name'

Используйте ISOString для представления метки времени

Хотя в graphql нет скалярного типа для представления временной метки, вы можете настроить скалярный DateTime для представления времени. формат времени

Обратитесь к вопросу на StackOverflowthe-right-json-date-format

const date = new Date()

// 从 toJSON 的输出就知道前后端交互需要使用什么格式了
date.toJSON()
// 2019-03-14T07:41:08.500Z
date.toISOString()
// 2019-03-14T07:41:08.500Z

Возвращаемый таким образом формат не только соответствует спецификации, но и более удобочитаем.

Я видел временные метки, возвращаемые в API, выраженные в трех форматах: временная метка unix, временная метка js и iso8601, что сбивает с толку. Унифицированный формат данных способствует совместной отладке клиентской и серверной частей, но это также выигрывает от строго типизированной схемы graphql.

структурированные сообщения об ошибках

вернется в graphql{ data, errors }Структура данных, сообщение об ошибке может быть структурировано в конце как

{
  "code": "InvalidToken",
  "message": "Token 失效",
  "httpStatus": 401
}

messageСообщения об ошибках для удобства чтения могут отображаться непосредственно во внешнем интерфейсе,codeДля отладки,httpStatusЗахвачено следующим промежуточным программным обеспечением, установите код состояния.

После структурирования сообщения об ошибке сообщение об ошибке может быть случайно отправлено в систему сигнализации (например, Sentry). Однако следует различать ПРЕДУПРЕЖДЕНИЕ и ОШИБКУ, например, 401 и 403 следует обрабатывать как ПРЕДУПРЕЖДЕНИЕ.

Стандартный http-статус

Хорошо. Строка graphql ошибочна. графqlQueryиMutationоба используютPOSTпросить. успешное выполнение различныхMutationВозврат разных 200, 201, 202 еще более хлопотный.

Однако для ошибок возвращаются разные коды состояния.Когда вы открываете devtool, вы можете сразу увидеть красную информацию 4XX, которая также полезна для быстрого обнаружения ошибочных запросов и немного снижает раздражительность.

Введите несколько общих кодов состояния 4xx

  • 401 Unauthorized: пользователь не вошел в систему, чтобы запросить ресурс, который требует входа в систему для запроса.
  • 403 Запрещено: пользователь А вошел в систему, но хочет запросить ресурсы Б
  • 400 Bad Request: Ну, я поставил все ошибки с кодом состояния не найден на 400

Около 400 ссылок400 BAD request HTTP error code meaning?Вот статья,О выборе кода состояния 4xx, сфотографировать

如何选择http错误状态码

Проверка данных запроса и ответа

Из-за строго типизированной схемы graphql проверка ввода и вывода данных также не выполняется.

Для Rest API схема JSON может использоваться для проверки формата данных. узел также может использоватьjoiСделайте проверку данных.

Вот документ схемы JSON:json-schema.org/

Документация комментариев

Благодаря самоанализу graphql и строго типизированной схеме. graphql может автоматически генерировать документацию на основе исходного кода и комментариев, а также использовать graphiql или графическую игровую площадку для непосредственного просмотра.

Если вы используете node.js для написания серверных приложений, вы можете использоватьapiDoc

Кроме того, будьте осторожны, чтобы не подвергать документацию производственной среде, graphql должен отключить самоанализ в производственной среде.