Руководство по настройке сервера Apollo в Node.JS для подключения к источнику данных RESTful
В этой короткой статье давайте рассмотрим, как мы могли бы создать простой запрос graphQL, который извлекает данные из конечной точки RESTful. Для этой цели мы будем использовать Node.js и Apollo Server.
В этой статье мы рассмотрим в качестве примера простой ресурс Users
. Цель этой статьи — просто описать шаги и конфигурации, необходимые для создания запроса, который использует существующую конечную точку REST в качестве источника данных, используя сервер apollo graphQL.
Больше контента на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord.
Хотите повысить узнаваемость и принятие вашего технологического стартапа? Посмотрите Цирк.
Это может пригодиться, если вы хотите предоставить клиенту-потребителю больше контроля над тем, какие поля должны отображаться в ответе.
Без лишних слов, давайте начнем:
Инициализируйте проект GraphQL:
Давайте создадим новый каталог с именем gserver
, а затем изменим каталог, набрав cd gserver
.
Теперь давайте инициируем проект с yarn init -y
Добавьте зависимости:
Нашими основными зависимостями являются пакеты graphQL и apollo-server. Итак, давайте добавим их в проект:
yarn add apollo-server graphql
Чтобы включить автоматический перезапуск сервера при изменениях во время разработки, добавим nodemon
в качестве dev-зависимости:
yarn add --dev nodemon
Теперь наш package.json должен выглядеть примерно так:
{ "name": "gserver", "version": "1.0.0", "main": "index.js", "license": "MIT", "type": "module", "dependencies": { "apollo-server": "^3.10.2", "graphql": "^16.6.0" }, "devDependencies": { "nodemon": "^2.0.19" } }
Примечание. Я использую Yarn
в качестве менеджера пакетов, но вы можете использовать npm
, если хотите.
Создайте индексный файл:
В корне проекта создайте файл с именем index.js
, который будет точкой входа для нашего сервера graphQL.
// index.js import { ApolloServer } from "apollo-server"; const server = new ApolloServer(); server .listen({port: process.env.PORT || 5000}) .then(({url})=> console.log(`gserver at : ${url}`));
Теперь, когда у нас настроен базовый сервер graphQL, давайте добавим скрипт в наш package.json
, чтобы запустить его в режиме разработки с nodemon
:
{ ...existing package.json content "scripts": { "dev": "nodemon index.js" } ... remaining content }
Создайте схему пользователя:
Схемы — это способы, которыми мы определяем типы и, следовательно, базовые структуры для запросов и мутаций в graphQL.
Давайте быстро создадим каталог с именем schema
в корне проекта.
Мы будем использовать специальный тег gql
для определения наших схем.
Схема пользователя может быть определена следующим образом:
// schema/user.js import { gql } from "apollo-server"; export const User = gql` type User { id: ID!, email: String, name: String } `
для UUID мы используем специальный тип в graphQL под названием ID
, а отметка !
означает, что он не может быть нулевым.
Таким образом, мы определили тип с именем User и создали схему для нашего пользовательского объекта.
Определите запрос пользователей:
В graphQL queries
, который извлекает данные (можно считать эквивалентным запросу GET в терминах REST), а также должен иметь четко определенную схему. В этом примере мы просто хотели бы получить всех пользователей из базовой конечной точки пользовательской службы. Итак, давайте определим наш запрос, чтобы получить всех пользователей:
// schema/query.js import { gql } from "apollo-server"; export const Query = gql` type Query { users: [User] } `
Поскольку с помощью запроса users
мы получим более одного пользователя, мы указываем его тип как массив типа User (который мы определили ранее в схеме).
Для простоты импорта давайте создадим индексный файл в каталоге схемы и предоставим определенную схему следующим образом:
// schema/index.js export { User } from './user.js'; export { Query } from './query.js';
Запустите сервер:
давайте изменим точку входа нашего сервера index.js
, чтобы включить схемы, которые мы определили:
// index.js import { ApolloServer } from "apollo-server"; import { Query, User } from "./schema/index.js"; const server = new ApolloServer({typeDefs:[Query,User]}); server .listen({ port: process.env.PORT || 5000 }) .then(({ url }) => console.log(`gserver at : ${url}`));
Теперь давайте наберем yarn dev
в терминале:
когда мы открываем наш браузер по адресу http://localhost:5000
, если все прошло хорошо, мы должны увидеть следующий экран:
Когда вы нажмете кнопку Query Your Server
, вы попадете в студию Apollo, где сможете найти определенную схему:
мы еще многого не можем. поэтому давайте добавим преобразователь для получения информации о пользователях в следующем разделе.
Служба RESTful для пользователей:
У нас есть служба users
, работающая на порту 3000, которая в настоящее время возвращает следующий ответ для конечной точки localhost:3000/users
:
Это обычная конечная точка RESTful, работающая на экспресс-сервере. Нам не нужно сильно беспокоиться о его реализации, поскольку основное внимание в этой статье уделяется взаимодействию существующей конечной точки REST с запросом graphQL.
Пользователи DataSource и Resolver:
Теперь нам нужно сопоставить наш запрос graphQL users
для получения данных из указанной выше конечной точки RESTful. Мы могли бы сделать этот graphQL, определив dataSource
, а затем сопоставив его с resolver
.
В этом разделе мы увидим, как это сделать, чтобы получить всех наших пользователей из конечной точки Rest.
Источник данных пользователей:
Поскольку мы собираемся использовать конечную точку отдыха в качестве источника данных, давайте установим пакет apollo-datasource-rest
, созданный командой Apollo. Этот пакет заботится о таких важных вещах, как кэширование, поэтому нам не нужно об этом беспокоиться.
Добавим пакет в наш проект:
yarn add apollo-datasource-rest
Теперь давайте создадим каталог с именем datasource
в корне нашего проекта и определим следующее:
// datasource/users.js import { RESTDataSource } from "apollo-datasource-rest"; export class UsersAPI extends RESTDataSource { constructor(){ super(); this.baseURL = "http://localhost:3000/" } async getAllUsers() { return this.get('users') } }
baseURL
должен быть базовым URL-адресом для нашего users
service.
Индексный файл для каталога datasource
будет следующим:
// datasource/index.js import { UsersAPI } from "./users.js"; export const dataSources = () => ({ UsersAPI: new UsersAPI() });
Резолвер пользователей:
Давайте добавим наш преобразователь, чтобы получить всех пользователей. мы создадим каталог с именем resolvers
в корне проекта и добавим в него следующее:
// resolvers/users.js export const userResolvers = { users: (parent, args, {dataSources}, info) => dataSources.UsersAPI.getAllUsers() }
Это будет иметь смысл, когда мы свяжем его с точкой входа сервера в следующем сеансе. Для индекса resolvers
добавим следующее:
// resolvers/index.js import { userResolvers } from "./users.js"; export const resolvers = { Query: { ...userResolvers } }
Подключите его к серверу:
Мы подключим источник данных и преобразователь к нашему серверу, изменив файл index.js
в корне проекта следующим образом:
// index.js import { ApolloServer } from "apollo-server"; import { Query, User } from "./schema/index.js"; import { resolvers } from "./resolver/index.js"; import { dataSources } from "./datasource/index.js"; const server = new ApolloServer({ typeDefs:[Query,User ], resolvers, dataSources }); server .listen({ port: process.env.PORT || 5000 }) .then(({ url }) => console.log(`gserver at : ${url}`));
Теперь мы можем перейти на нашу игровую площадку graphQL, работающую по адресу localhost:5000
, и выполнить запрос для получения всех пользователей следующим образом:
Как мы видим, в отличие от конечной точки REST, которая возвращает нам все поля, в запросе graphQL мы можем выбрать только те поля, которые нам нужны, из схемы users
.
Заключение:
Таким образом, мы создали работающий запрос graphQL, который извлекает данные из существующей конечной точки REST. Мы также увидели, какие различные компоненты и конфигурации необходимы, и как они связаны друг с другом, чтобы это произошло.