Уф, это полный рот. В первой части серии мы рассмотрим настройку экспресс-схем и схем GraphQL.
Если вы хотите узнать больше о том, почему выбрать GraphQL вместо архитектуры REST, вот ссылка, по которой вы можете перейти, чтобы узнать больше.
Https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b
Давайте начнем.
mkdir server cd server touch app.js npm init
Мы хотим запустить новый пустой проект и init. Вы можете просто нажать Enter после npm init или дать проекту имя.
npm install express graphql express-graphql
Наши пакеты для настройки express, и нам нужен express-graphql, потому что обычный экспресс не знает, как обрабатывать запросы graphql.
// app.js const express = require('express') const graphqlHTTP = require('express-graphql') const app = express() // binding graphql to express app.use('/graphql', graphqlHTTP({ })); app.listen(4000, () => { console.log('now listening for requests on port 4000'); });
Теперь мы говорим express, что хотим использовать localhost: 4000 / graphql для обработки всех наших запросов. Но если вы пойдете туда сейчас, то увидите ошибку. Убедитесь, что вы запускаете приложение в терминале! Если у вас нет nodemon, я настоятельно рекомендую npm i -g nodemon. Он следит за вашими файлами на предмет изменений, поэтому это отличный инструмент для разработки.
nodemon app.js
Нам нужно сообщить express-graphql о схеме данных, чтобы он знал, как данные выглядят, и как их обслуживать и разрешать. Итак, давайте спроектируем схему!
mkdir schema cd schema touch schema.js
Здесь мы создадим файл схемы.
// schema.js const graphql = require('graphql') const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLBoolean, GraphQLSchema } = graphql const TaskType = new GraphQLObjectType({ name: 'Task', fields: () => ({ id: { type: GraphQLInt }, name: { type: GraphQLString }, completed: { type: GraphQLBoolean } }) }) const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: { task: { type: TaskType, args: { id: { type: GraphQLInt } }, resolve(parent, args) { // code to get data from db } } } }) module.exports = new GraphQLSchema({ query: RootQuery })
Много чего только что произошло. Мы определяем очень простой тип задачи или, если хотите, «модель». Все, что он знает, - это то, какие данные он хранит. Следующая часть - это наш корневой запрос, с помощью которого мы переходим в структуру графа и находим что-то. Аргумент «поля» - это термин запроса. Нам обязательно нужно будет его расширить, так как это только один. Может быть, что-то вроде «задач», которое вернет список всех задач. Давайте рассмотрим этот запрос, который мы написали выше. «Задача» - это то, что мы будем запрашивать, и нам нужно передать аргумент «id», который затем вернет все, что найдено в базе данных с этим идентификатором. Если это не имеет смысла, я думаю, что в следующем разделе будет показан пример.
Но сначала давайте добавим эту схему в наше экспресс-приложение.
// app.js const schema = require('./schema/schema') const express = require('express') const graphqlHTTP = require('express-graphql') const app = express() app.use('/graphql', graphqlHTTP({ schema: schema })) ...
Хороший! Мы успешно подключили схему и все, что нам нужно, чтобы поиграть! А пока давайте воспользуемся фиктивными данными и настроим сервер в следующем руководстве. Нам также понадобится способ проанализировать эти данные и получить идентификатор.
// schema.js ... const tasks = [ { name: 'Go to the grocery store', completed: false, id: 1 }, { name: 'Pick up dry cleaning', completed: true, id: 2 }, { name: 'Write GraphQL tutorial', completed: false, id: 3 }, { name: 'Clean up garage', completed: false, id: 4 }, { name: 'Make a really good sandwich', completed: true, id: 5 } ] function find(collection, id){ for (const key of Object.keys(collection)) { if (collection[key].id === id) return collection[key] } } const TaskType = new GraphQLObjectType({ name: 'Task', fields: () => ({ id: { type: GraphQLInt }, name: { type: GraphQLString }, completed: { type: GraphQLBoolean } }) }) const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: { task: { type: TaskType, args: { id: { type: GraphQLInt } }, resolve(parent, args) { return find(tasks, args.id) } } } }) module.exports = new GraphQLSchema({ query: RootQuery })
Итак, теперь все, что нам нужно сделать, это протестировать! К счастью, в graphql есть отличный инструмент под названием «graphiql», который представляет собой игровую площадку для тестирования ваших запросов. Давайте добавим этот инструмент.
// app.js const express = require('express') const graphqlHTTP = require('express-graphql') const app = express() const schema = require('./schema/schema') app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true })) app.listen(4000, () => { console.log('now listening for requests on port 4000') })
Посмотрите http: // localhost: 4000 / graphql, и вы увидите экран, показанный ниже!
Слева есть несколько полезных советов о том, как начать работу с запросами, а справа - самодокументированный дизайн схемы. Это так круто! Вы также можете изучить документацию справа, чтобы узнать, какие данные ожидаются и как использовать запрос. Давайте попробуем наш единственный запрос.
query { task(id: 1) { id name completed } }
И ответ ...
{ "data": { "task": { "id": 1, "name": "Go to the grocery store", "completed": false } } }
Хорошо! Мы работаем с express и graphql. Не так уж сложно, правда? В следующем руководстве мы рассмотрим другие запросы и настройку базы данных. А пока попробуйте добавить свои собственные запросы!