Введение
В этой статье вы узнаете, как создавать серверы GraphQl с помощью Express в NodeJS. GraphQl — это быстрый и простой способ создания бэкендов, которые эффективно взаимодействуют с фронтендами и контролируют ресурсы.
Предварительные условия
В этой статье рассматриваются только основы GraphQL, поэтому для полного понимания ее содержания необходимо знание NodeJS и ExpressJS.
Что такое GraphQL?
GraphQL — это язык запросов к данным с открытым исходным кодом и среда выполнения для создания API и ответов на запросы с использованием существующих данных. GraphQL позволяет очень просто создавать бэкенд API. Чтобы получить все необходимые данные с сервера, приложению достаточно одного запроса к API GraphQL вместо отправки нескольких запросов к нескольким конечным точкам.
API GraphQL можно создавать на распространенных языках программирования, таких как Python, Java, JavaScript, Scala, Ruby и многих других. Любой тип приложения может взаимодействовать с GraphQL API, если оно может делать запросы к конечной точке.
Преимущества GraphQL
API GraphQl имеют множество преимуществ по сравнению с RESTful API. К ним относятся:
- Получение точных данных: В GraphQL мы можем получить от сервера именно то, что нам нужно, используя запрос. В отличие от REST API, которые предоставляют все данные, которые могут быть получены из конечной точки, что делает взаимодействие между сервером и клиентами очень медленным и неэффективным.
- Получение больших объемов данных с помощью одного запроса: С помощью GraphQL API мы можем получить все данные, необходимые нашему приложению, за один запрос, в отличие от большинства REST API, которые требуют загрузки с нескольких конечных точек.
- Богатая система типов: API GraphQL не используют конечные точки для организации. Вместо этого они организованы по типам и полям, что помогает выдавать полезные сообщения, если сервер сталкивается с какой-либо ошибкой. GraphQL использует одну конечную точку, обычно с именем «/graphql», которую клиент использует для связи с бэкендом.
- Единый дизайн API: API GraphQL имеют единый дизайн для различных языков программирования. API GraphQL не требуют значительных изменений для переноса с одного языка программирования на другой. В GraphQL мы используем схему для описания того, что может делать наш API. В GraphQL легко создавать объекты, соответствующие схеме.
Построение RESTful API с помощью Express
Прежде чем создавать наш API с помощью GraphQL, мы создадим его REST-версию. Созданный нами API будет иметь две конечные точки:
- /say-message, которая отвечает сообщением с сервера.
- /change-message, которая изменяет сообщение на сервере.
Чтобы создать этот API, мы выполним следующие шаги в папке нашего уже инициализированного проекта:
- Установите пакет express, используя любую из следующих команд:
Менеджер пакетов | Команда |
Yarn | npm install express |
Npm | yarn add express |
- Создайте файл index.js и напишите в нем следующее:
// import the express library
const express = require('express');
// create the express application
const app = express();
// register the "express.text()" middleware to parse incoming text requests
app.use(express.text());
// This variable stores a string that the endpoints below manipulate
let text = "Hello, World";
// create an endpoint to get the `text` string
app.get("/say-message", (req, res) => {
// send a response with text
res.send(text);
});
// create an endpoint to change the `text` string
app.post("/change-message", (req, res) => {
// change the text of "text" variable to the one sent in the request
text = req.body;
// send a response with text
res.send(text);
});
// Run the server on localhost port 8080
app.listen(8080, () => console.log("Server running...."));
Если мы выполним следующие запросы в нашем фронтенде, мы получим следующие ответы от сервера:
Действие | Запрос фронтенда | Ответ |
Получение сообщения с сервера | fetch(«http://localhost:8080»)
.then(req => req.text()) .then(message => console.log(message)); |
Привет, мир! |
Изменение сообщения на сервере | // изменить сообщение
fetch(«http://localhost:8080», { ‘method’: ‘POST’, ‘headers’: { ‘Content-type’: ‘application/text’, }, ‘body’: ‘Humans’ }) .then(req => req.text()) .then(message => console.log(message)); // получаем сообщение fetch(«http://localhost:8080») .then(req => req.text()) .then(message => console.log(message)); |
Привет, люди! |
Построение API с помощью GraphQL и Express
В этом разделе мы построим GraphQL-версию API, который мы создали выше. Для создания API нам необходимо установить следующие библиотеки:
- graphql, чтобы использовать основные возможности graphql в нашем коде.
- express, для создания конечной точки graphql.
- express-graphql, для использования graphql в приложении express.
Для установки вышеперечисленных библиотек мы используем любую из следующих команд:
Менеджер пакетов | Команда |
Yarn | yarn add express graphql express-graphql |
Npm | npm install express graphql express-graphql |
После установки библиотек мы создадим файл index.js и скопируем в него следующее:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
let schema = buildSchema(`
type Query {
message: String
}
type Mutation {
changeMessage(message: String): Boolean
}
`)
class Root {
text = "Hello, World!";
message() {
return this.text;
}
changeMessage({ message }) {
this.text = message;
return true;
}
}
const app = express();
app.use('/graphql', graphqlHTTP({
graphiql: true,
schema: schema,
rootValue: new Root(),
}))
app.listen(8080, () => {
console.log("Server running...");
})
Ниже приводится пояснение к приведенной выше программе:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
- В приведенном выше фрагменте мы импортировали следующее:
- express, функция-конструктор для создания бэкенд-приложений
- graphqlHttp, промежуточная функция express для использования graphql в приложении
- buildSchema, функция из graphql, которая создает схему, используя язык схем.
let schema = buildSchema(`
type Query {
message: String
}
type Mutation {
changeMessage(message: String): Boolean
}
`)
- В приведенном выше фрагменте мы построили нашу схему с помощью языка схем graphql. В GraphQL схема — это описание запросов, которые клиент может делать к бэкенду. Схема определяет все запросы и мутации, которые могут выполнять клиенты. Запросы возвращают данные с сервера, а мутации изменяют данные на сервере.
class Root {
text = "Hello, World!";
message() {
return this.text;
}
changeMessage({ message }) {
this.text = message;
return true;
}
}
- В приведенном выше фрагменте мы создаем класс, который определяет методы для схемы. Просто иметь схему недостаточно, нам также необходимо ее реализовать. Мы используем класс для создания интерфейса между нашим бэкендом и GraphQL. Этот класс определяет методы, которые отвечают на конкретный запрос, сделанный к api.
const app = express();
app.use('/graphql', graphqlHTTP({
graphiql: true,
schema: schema,
rootValue: new Root(),
}))
- В приведенном выше фрагменте мы создаем наше приложение, вызывая фабричную функцию express. Затем мы регистрируем промежуточную функцию graphqlHTTP для конечной точки /graphql. В промежуточную функцию graphqlHTTP мы передаем объект, который содержит следующее:
- graphiql, чтобы включить GUI, который выглядит как на рисунке ниже, для тестирования запросов graphql.
- schema, для регистрации схемы, которую мы создали.
- rootValue, чтобы зарегистрировать корневой объект для graphql.
В приведенном выше интерфейсе, если мы выполним следующие запросы в порядке, указанном в таблице ниже, мы получим следующие ответы:
Запрос | Ответ |
запрос {
сообщение } |
{
«данные»: { «сообщение»: «Hello, World!» } } |
мутация {
changeMessage(message: «Humans») } |
{
«data»: { «changeMessage»: true } } |
запрос {
сообщение } |
{
«данные»: { «сообщение»: «Hello, Humans!» } } |
В GraphQL запрос может быть либо запросом, либо мутацией, но не тем и другим, что означает, что вы не можете отправить запрос, как показано ниже:
mutation {
changeMessage(message: "Humans")
}
query {
message
}
В таблице ниже представлены схемы, запросы и классы для различных типов способов создания и взаимодействия с приложениями GraphQL.
Тип | Тело запроса | Схема | Базовый класс |
Одиночный запрос | запрос {
сообщение } |
тип Запрос {
сообщение: Строка } |
class Root {
сообщение() { … } } |
Мультизапрос | запрос {
сообщение число } |
тип Запрос {
сообщение: Строка число: Int } |
class Root {
сообщение() { … } number() { … } } |
Вложенный мультизапрос | запрос {
сообщение дополнительные данные { число } } |
тип Запрос {
сообщение: Строка extraData: ExtraData } тип ExtraData { число: Int } |
class Root {
сообщение() { … } extraData() { … return new ExtraData(); } } class ExtraData { number() { … } } |
Одиночный запрос с аргументами | запрос {
сообщение (текст: «Привет») } |
тип Запрос {
message(text: String): String } |
class Root {
message({ text }) { … } } |
Одиночная мутация | мутация {
сообщение(текст: «Привет») } |
тип Мутация{
message(text: String): String } |
class Root {
сообщение({ текст }) { … } } |
Мультимутация | мутация {
сообщение(текст: «Привет») возраст(число: 18) } |
тип Мутация {
message(text: String): Строка возраст(число: Int): Int } |
class Root {
message({ text }) { … } возраст({ число }) { … } } |
Вложенная мультимутация | мутация {
сообщение(текст: «Привет») свойства { возраст (число: 18) } } |
тип Мутация {
сообщение(текст: String): String свойства: Свойства } тип Свойства { возраст(число: Int): Int } |
class Root {
сообщение({ текст }) { … } properties() { … return new Properties(); } } class Properties{ возраст({ число }) { … } } |
Заключение
В этой статье мы рассмотрели основы создания API с помощью Express, фреймворк GraphQL и создание API на основе GraphQL. GraphQL — это быстрый и простой способ объединить фронтенд и бэкенд приложения вместе. Надеюсь, эта статья поможет лучше понять создание API с помощью GraphQL. Чтобы углубить свои знания по этой теме, вы можете воспользоваться следующими ссылками:
- Введение в GraphQL
- Express 5.x — Справочник по API
- GraphQL — схемы и типы