GraphQL - это просто язык запросов для вашего API. Я считаю GraphQL действительно хорошей альтернативой REST. GraphQL делает интерфейсное программирование очень простым, поскольку он позволяет использовать единую конечную точку, что сокращает время отклика и позволяет избежать избыточной и недостаточной выборки.
Однако эти преимущества достигаются за счет стоимости, которая включает в себя настройку сервера, запроса схемы и resolver.
Здесь я объясню, как подключить GraphQL к PostgreSQL.
Для взаимодействия с базой данных вы можете использовать те же библиотеки коннекторов данных, которые вы обычно используете. Единственное, что вам нужно сделать, это правильно реализовать методы разрешения запросов и мутаций.
База данных PostgreSQL
CREATE TABLE people ( id serial PRIMARY KEY, firstname varchar(40) NOT NULL, lastname varchar(40) NOT NULL ); CREATE TABLE emails ( id serial PRIMARY KEY, email varchar(256) NOT NULL, person integer REFERENCES people (id), “primary” boolean DEFAULT false );
Первая таблица представляет людей, а вторая - электронные письма людей.
Схема GraphQL
Query { person(id: ID): Person } type Person { id: ID firstname: String lastname: String emails: [Email!]! } type Email { id: ID email: String primary: Boolean }
Запрос
SELECT * FROM "emails" WHERE person=person.id;
Я хочу получить все электронные письма, которые есть у конкретного человека.
На первом этапе преобразователь GraphQL извлекает человека из базы данных, второй шаг - это идентификатор человека и получение электронных писем для него.
1. Настройте Express Server.
const express = require('express'); const expressGraphQL = require('express-graphql'); const schema = require('./schema'); const app = express(); app.use('/graphql', expressGraphQL({ schema, graphiql: true })) app.listen(4000, () => { console.log('Listening...') })
Сначала вам нужно установить express, а затем express-graphql.
Позже вы увидите, как настроить схему, которая мне нужна, вверху.
Кроме того, для Graphiql установлено значение true. Graphiql - это среда разработки GraphQL, в которой я могу легко проверять свои запросы. Когда GraphiQL делает запрос, GraphQL обращается к моей базе данных и говорит: «Я ищу этого конкретного человека». Если вам интересно, наш запрос будет асинхронным.
2. Настройка схемы GraphQL
const graphql = require('graphql'); const connectionString = 'myURI'; const pgp = require('pg-promise')(); const db = {} db.conn = pgp(connectionString); const { GraphQLObjectType, GraphQLID, GraphQLString, GraphQLBoolean, GraphQLList, GraphQLSchema } = graphql; const PersonType = new GraphQLObjectType({ name: 'Person', fields: () => ({ id: { type: GraphQLID }, firstname: { type: GraphQLString }, lastname: { type: GraphQLString }, emails: { type: new GraphQLList(EmailType), resolve(parentValue, args) { const query = `SELECT * FROM "emails" WHERE person=${parentValue.id}`; return db.conn.many(query) .then(data => { return data; }) .catch(err => { return 'The error is', err; }); } } }) }) const EmailType = new GraphQLObjectType({ name: 'Email', fields: { id: { type: GraphQLID }, email: { type: GraphQLString }, primary: { type: GraphQLBoolean } } }) const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: { person: { type: PersonType, args: { id: { type: GraphQLID } }, resolve(parentValue, args) { const query = `SELECT * FROM "people" WHERE id=${args.id}`; return db.conn.one(query) .then(data => { return data; }) .catch(err => { return 'The error is', err; }); } }, emails: { type: EmailType, args: { id: { type: GraphQLID } }, resolve(parentValue, args) { const query = `SELECT * FROM "emails" WHERE id=${args.id}`; return db.conn.one(query) .then(data => { return data; }) .catch(err => { return 'The error is', err; }); } } } }) module.exports = new GraphQLSchema({ query: RootQuery })
Я использую pg-обещание для подключения к своей базе данных. Затем я определяю все типы, которые собираюсь использовать.
Вы можете увидеть разницу между полями в EmailType и PersonType. Поля электронной почты представляют собой простой объект, но PersonType имеет функцию стрелки.
Почему?
Если мы просто оставим простой объект и захотим выполнить этот код, мы получим ошибку: «EmailType не определен». Это происходит потому, что компилятор Javascript не знает о EmailType при определении PersonType, потому что EmailType определяется после PersonType.
Мы можем переместить EmailType перед PersonType, и он будет работать, но что, если внутри EmailType у нас есть другое свойство, которое связано с PersonType. Благодаря тому, что закрытие внутри javascript работает - функция определяется, но не запускается до тех пор, пока не будет выполнен весь этот файл. Это не проблема GraphQL, это проблема Javascript при работе с замыканиями и областями закрытия.
Начните свой код с:
node server.js
Визит:
http://localhost:4000/graphql
Добавить клиентский запрос:
query { person(id: "1") { id firstname lastname emails { id email verified } } }
Запустите запрос и посмотрите результаты. :)
Я надеюсь, что этот базовый пример поможет вам лучше понять GraphQL.