Въведение
През последните години нови рамки, библиотеки и езици намериха своя път на технологичната сцена и се бореха да получат масово приемане, но скорошна част от технологията, която беше широко усвоена от екипите за софтуерно инженерство за кратък период от време, е GraphQL. Издаден от Facebook през 2015 г., той е внедрен на множество езици за програмиране и доведе до създаването на няколко свързани с GraphQL рамки и библиотеки.
GraphQL е строго въведен език за заявки за API и среда за изпълнение за изпълнение на заявки със съществуващи данни. Той позволява на клиентите да правят заявки за много ресурси в една заявка, като изискват задължителни полета, вместо да правят заявки до множество крайни точки.
Apollo Server е GraphQL сървър с отворен код, който предоставя лесен начин за изграждане на GraphQL API, който може да използва данни от множество източници, включително няколко бази данни и дори REST API.
MongoDB Atlas е напълно управлявана платформа за данни за приложения, която обработва създаването, управлението и внедряването на MongoDB в облака. Той осигурява лесно внедряване на бази данни MongoDB на различни доставчици на облачни услуги с няколко инструмента за управление на бази данни MongoDB в производствена среда.
В този урок ще научим как да изградим и разгърнем GraphQL сървър, свързан с източник на данни MongoDB. В края на този урок ще сте изградили функционален GraphQL API, използвайки Apollo Server и MongoDB Atlas и ще го разгърнете в производство на Koyeb.
Изисквания
За да следвате успешно този урок, имате нужда от следното:
- Машина за разработка с инсталиран Node.js. Демонстрационното приложение в този урок използва версия 16.14.0 на Node.js
- Машина за разработка с инсталиран Git
- Профил в MongoDB Atlas
- Акаунт в Koyeb за внедряване на приложението
Стъпки
Стъпките за създаване на GraphQL API с Apollo DataSource и MongoDB Atlas и внедряването му в производство на Koyeb включват:
- Създайте база данни MongoDB с помощта на MongoDB Atlas
- Настройте проекта
- Създайте GraphQL сървър с помощта на Apollo Server
- Свържете GraphQL сървъра към базата данни MongoDB
- Използвайте MongoDB като източник на данни за GraphQL
- Разгръщане в Koyeb
Създайте база данни MongoDB с помощта на Mongo Atlas
MongoDB Atlas предлага възможност за създаване на бази данни MongoDB, разположени в облака, само с няколко щраквания и в този раздел ще създадете база данни MongoDB с помощта на MongoDB Atlas.
Докато сте влезли в акаунта си в MongoDB Atlas, щракнете върху бутона „Създаване на база данни“ на страницата „Внедряване на данни“ и изпълнете следните стъпки:
- Щракнете върху бутона „Създаване“ на предпочитания от вас тип внедряване.
- Изберете предпочитан доставчик на облак и регион или използвайте предварително избраните опции.
- Въведете име на клъстер или използвайте името на клъстера по подразбиране.
- Щракнете върху бутона „Създаване на клъстер“.
- Изберете опцията за удостоверяване „Потребителско име и парола“, въведете потребителско име и парола и щракнете върху бутона „Създаване на потребител“. Съхранявайте потребителското име и паролата на безопасно място за по-късна употреба.
- Въведете „0.0.0.0/0“ без кавичките в полето за IP адрес на секцията IP Access List и кликнете върху бутона „Добавяне на запис“.
- Щракнете върху бутона „Край и затваряне“ и след това върху бутона „Отиди към бази данни“. Ще бъдете пренасочени към страницата „Разгръщане на данни“, като вашият нов MongoDB клъстер вече се вижда.
- Щракнете върху бутона „Свързване“ до името на клъстера на MongoDB, изберете опцията „Свържете приложението си“ и копирайте низа си за връзка с база данни на безопасно място за по-късна употреба.
Следвайки стъпките по-горе, вие създадохте база данни MongoDB за четене и съхраняване на данни за GraphQL API. В следващия раздел ще настроите проекта и ще инсталирате необходимите библиотеки и зависимости.
Настройте проекта
В този раздел ще настроите npm проект и ще инсталирате необходимите зависимости за изграждане на демонстрационния GraphQL сървър за този урок. Сървърът на GraphQL ще разкрие GraphQL API, който чете и записва филмови данни от и в базата данни MongoDB, създадена в предишния раздел. Започнете със създаване на главна директория за проекта на вашата машина за разработка. За да направите това, изпълнете командата по-долу в прозореца на терминала:
mkdir graphql_movies
graphql_movies
директорията, създадена от командата по-горе, е основната директория за демонстрационното приложение. След това преминете към graphql_movies
директория и инициализирайте Git хранилище в директорията, като изпълните командата по-долу във вашия терминален прозорец:
cd graphql_movies
git init
Първата команда по-горе ви премества в graphql_movies
директория във вашия терминал, докато втората команда инициализира Git хранилище за проследяване на промените в graphql_movies
директория. След това създайте npm проект в graphql_movies
директория, като изпълните командата по-долу във вашия терминален прозорец:
npm init --yes
Изпълняване на npm init
командата инициализира празен npm проект и създава package.json
файл в основната директория. --yes
флагът автоматично отговаря с "да" на всички подкани, повдигнати от npm.
С вече създаден npm проект, продължете и инсталирайте библиотеките и пакетите, необходими за изграждане на GraphQL API. В прозореца на терминала изпълнете командите по-долу:
npm install apollo-server graphql mongoose apollo-datasource-mongodb dotenv rimraf
npm install -D @babel/preset-env @babel/core @babel/node @babel/cli
npm install
командата по-горе инсталира 10 пакета в проекта и ги добавя към package.json
на проекта файл. Първата команда инсталира зависимости, необходими за стартиране на приложението, докато втората инсталира зависимости, необходими при разработването на приложението. Инсталираните зависимости включват:
- apollo-server:Библиотека с отворен код за изграждане на GraphQL сървъри.
- graphql:JavaScript реализацията на спецификацията GraphQL.
- mongoose:Преобразувател на обектни документи за MongoDB.
- apollo-datasource-mongodb:Библиотека с източници на данни на Apollo за MongoDB.
- dotenv:Библиотека за работа с променливи на средата.
- rimraf:Библиотека за изпълнение на UNIX
rm -rf
команда в Node.js.
Другите библиотеки, инсталирани за разработка, включват хост от babel
библиотеки за изпълнение и транспилиране на модерен JavaScript код.
След това създайте .babelrc
файл в основната директория на проекта и добавете следния код към файла:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.0.0"
}
]
]
}
Кодът по-горе инструктира Babel как да транспилира най-новия JavaScript код, присъстващ в приложението, използвайки env
на Babel опции за конфигурация.
И накрая, създайте src
папка в главната директория на проекта. Това src
папката ще съдържа всички файлове на проекта. С тези промени структурата на проекта е на мястото си и в следващия раздел ще създадете GraphQL сървър, използвайки библиотеката на Apollo Server.
Създайте GraphQL сървър с помощта на Apollo Server
В този раздел ще създадете GraphQL сървър с помощта на Apollo Server. Библиотеката на Apollo Server се предлага с вграден Express сървър и може да изпълнява GraphQL заявки и мутации. Той също така предоставя пясъчна среда в браузъра за свързване към GraphQL сървър, писане и изпълнение на GraphQL заявки, преглед на резултатите от заявките и изследване на GraphQL схемата на сървъра.
Сървърът на GraphQL се състои от схема на GraphQL, която дефинира структурата на неговия API и преобразуватели, които реализират структурата на схемата. Схемата на GraphQL се състои от types
, който описва данните, които могат да бъдат заявени и върнати от GraphQL сървъра. GraphQL предоставя език за дефиниране на схема (SDL), използван за дефиниране на схема на GraphQL. Използвайки SDL на GraphQL, тип филм може да бъде дефиниран, както следва:
type Movie {
_id: ID!
title: String!
rating: Float!
year: Int!
}
Movie
Типът по-горе дефинира четирите полета, които могат да бъдат запитани за филм и техния тип връщане. GraphQL също има три основни типа; query
, mutation
и subscription
. Тези три типа служат като входни точки към GraphQL сървър и дефинират възможните изпълними операции в GraphQL сървър. query
типът е за операции за извличане на данни, mutation
типът е за операции за създаване или модифициране на данни и subscription
типът е за операции за извличане на данни в реално време.
За да създадете схема за GraphQL сървъра, създайте typeDefs.js
файл в src
папка и добавете следния код към файла:
import { gql } from 'apollo-server';
export const typeDefs = gql`
type Movie {
_id: ID!
title: String!
rating: Float!
year: Int!
}
type Query {
getMovies: [Movie!]!,
getMovie(id: ID!): Movie!
}
type Mutation {
createMovie(title: String!, rating: Float!, year: Int!): Movie!
}
`;
Кодът по-горе е дефиниция на типа на GraphQL схема и дефинира три типа GraphQL; Movie
, Query
и Mutation
. Query
и Mutation
Типовете са основните типове, докато Movie
мутацията дефинира заявените полета за филмови записи.
Query
тип в дефиницията на схемата по-горе включва следните полета:
getMovies
:Това поле връща масив от един или повечеMovie
тип обекти.getMovie
:Това поле приемаID
аргумент и връща единиченMovie
тип обект.
В допълнение, Mutation
тип включва createMovie
поле, което приема title
, rating
и year
аргумент и връща Movie
тип обект. Тези полета представляват заявките и мутациите, приети от GraphQL сървъра.
Когато заявките и мутациите в основните типове се изпълняват, GraphQL очаква съответните им функции на преобразуване да извличат и връщат данни, съответстващи на типа на връщане на схемата. За да добавите функции за преобразуване, създайте resolvers.js
файл в src
директория и добавете следния код към файла:
const movies = [{
_id: "12345",
title: "Sinder Twindler",
year: 2022,
rating: 6.5,
}];
export const resolvers = {
Query: {
getMovies: (_root, _args, _context, _info) => {
return movies;
},
getMovie: (_root, { id }, _context, _info) => {
return movies.find(({ _id }) => _id === id);
}
},
Mutation: {
createMovie: (_root, args, _context, _info) => {
const randomId = Math.random().toString().split('.')[1];
const newMovie = { ...args, _id: randomId }
movies.push(newMovie);
return newMovie;
}
}
}
В кода по-горе ние инициализираме масив от филми, който служи като временен източник на данни. В допълнение към това ние експортираме resolvers
обект с Query
и Mutation
свойства, които съответстват на Query
и Mutation
типове в дефиницията на схемата. Двете свойства на преобразувателя включват функции, които съответстват на операциите, декларирани в Query
и Mutation
видове. Тези функции на преобразувател изпълняват специфични действия върху източника на данни и връщат исканите данни.
Функцията за преобразуване на GraphQL приема четири аргумента:
root
:Този аргумент съдържа резултатите от всички стартирани по-рано резолвери.args
:Този аргумент съдържа параметрите за GraphQL заявка.context
:Този аргумент съдържа данни/обекти, които могат да бъдат достъпни/споделени между функциите на преобразувател.info
:Този аргумент съдържа информация за GraphQL заявката или мутацията, която се изпълнява.
Създадените схема и резолвери трябва да бъдат свързани към сървър, за да станат функционални. В src
директория, създайте index.js
файл и добавете следния код към файла:
import { ApolloServer } from 'apollo-server';
import { typeDefs } from './typeDefs'
import { resolvers } from './resolvers'
const server = new ApolloServer({typeDefs, resolvers})
server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Кодът по-горе импортира и създава екземпляр на сървъра Apollo. Схемата (typeDefs
) и резолверите също се импортират във файла и се предават на екземпляра на Apollo Server. И накрая, listen
на Apollo Server метод стартира уеб сървъра на предоставения порт или порт 4000, ако не е предоставен порт.
За да стартирате сървъра, добавете скрипта по-долу към package.json
файл, намиращ се в основната директория:
{
...
"scripts": {
…
"start:dev": "babel-node src/index.js"
},
...
}
start:dev
скриптът по-горе изпълнява кода в src/index.js
файл с помощта на babel-node
пакет. За да стартирате скрипта, изпълнете командата по-долу в прозореца на терминала:
npm run start:dev
Командата по-горе стартира уеб сървъра, който работи на порт 4000. Изпълнението на командата трябва да върне отговора по-долу:
🚀 Server ready at http://localhost:4000/
За да видите целевата страница на Apollo Server, посетете http://localhost:4000/
във вашия браузър. Трябва да видите страница като тази по-долу:
На целевата страница щракнете върху бутона „Запитване на вашия сървър“, за да бъдете пренасочени към тестовата среда в браузъра. Трябва да видите страница като тази по-долу, с предварително попълнена заявка за GraphQL:
Пясъчният бокс се състои от три панела; левият панел показва схемата на GraphQL API с наличните заявки и мутации, средният панел е за писане и изпълнение на заявки, а десният панел е за преглед на резултатите от заявките. Заменете заявката във вашата пясъчна кутия с кода по-долу:
query ExampleQuery {
getMovies {
_id
title
year
rating
}
}
Кодът по-горе добавя допълнителни полета към ExampleQuery
запитване. За да изпълните заявката, щракнете върху бутона "ExampleQuery", за да изпълните заявката. Трябва да видите отговора в десния панел.
В този раздел създадохте GraphQL сървър със заявки и мутации. В следващия раздел ще свържете GraphQL сървъра към база данни MongoDB.
Свържете GraphQL сървъра към базата данни Mongo
Функциите на преобразувателя в GraphQL сървъра в момента извлича данни от твърдо кодиран източник на данни вместо базата данни MongoDB, създадена в първия раздел. В този раздел ще свържете сървъра GraphQL към базата данни MongoDB и също така ще създадете модел на мангуста, който да представлява филмов документ в MongoDB.
Първо, създайте .env
файл в основната директория на проекта и добавете следния код към файла, където <username>
и <password>
представлява потребителя на базата данни на MongoDB и неговата парола:
MONGODB_URI="mongodb+srv://<username>:<password>@apollogql-demo.kk9qw.mongodb.net/apollogql-db?retryWrites=true&w=majority"
Кодът по-горе прави вашия низ за връзка с база данни MongoDB достъпен като променлива на средата. .env
файлът не трябва да бъде ангажиран с git, тъй като съдържа секретни данни.
След това заменете кода в src/index.js
файл със следното:
import 'dotenv/config'
import mongoose from 'mongoose';
import { ApolloServer } from 'apollo-server';
import { typeDefs } from './typeDefs';
import { resolvers } from './resolvers';
const uri = process.env.MONGODB_URI
const main = async () => {
await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true })
};
main()
.then(console.log('🎉 connected to database successfully'))
.catch(error => console.error(error));
const server = new ApolloServer({ typeDefs, resolvers })
server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Кодът по-горе импортира dotenv
config и mongoose
пакет в index.js
файл. Импортиране на dotenv
config прави променливи на средата в .env
файл, достъпен чрез process.env
обект. Стойността на MONGODB_URI
Променливата на средата се осъществява чрез process.env
и се съхранява в uri
променлива и асинхронна функция main
е обявен за създаване на връзка към базата данни MongoDB с помощта на mongoose connect
функция и uri
свързващ низ. main()
след това се извиква функция, за да отвори връзка с базата данни MongoDB.
🎉 connected to database successfully
🚀 Server ready at http://localhost:4000/
И накрая, създайте models
папка в src
папка и вътре в нея създайте movie.js
файл. Добавете кода по-долу към файла:
import mongoose from "mongoose";
export const Movie = mongoose.model("Movie", {
title: String,
rating: Number,
year: Number,
});
Кодът по-горе създава Movie
модел и служи като интерфейс за създаване и манипулиране на документи в базата данни MongoDB. Това е последната стъпка към превръщането на базата данни MongoDB в източник на данни за GraphQL сървъра. В следващия раздел ще превключите източника на данни на GraphQL сървъра от твърдо кодирания масив към вашата база данни MongoDB.
Използвайте MongoDB като източник на данни за GraphQL
Текущият източник на данни за GraphQL сървъра е твърдо кодиран масив и в този раздел ще го замените с вашата база данни MongoDB. За да направите това, започнете със създаване на dataSources
папка в src
папка. В dataSources
папка, създайте movies.js
файл и добавете следния код към файла:
import { MongoDataSource } from 'apollo-datasource-mongodb'
export default class Movies extends MongoDataSource {
async getMovies() {
return await this.model.find();
}
async getMovie(id) {
return await this.findOneById(id);
}
async createMovie({ title, rating, year }) {
return await this.model.create({ title, rating, year });
}
}
Кодът по-горе декларира Movies
клас източник на данни, който разширява MongoDataSource
клас, предоставен от apollo-datasource-mongodb
пакет. Movies
източникът на данни съдържа три метода за всяка от съществуващите заявки и мутация. getMovies
и createMovie
методите използват модела на филма, създаден в предишния раздел, за да четат и вмъкват данни в базата данни MongoDB и getMovie
методът използва findOneById
метод, предоставен от MongoDataSource
клас, за да извлечете документ от колекцията MongoDB, който съответства на предоставения id
аргумент.
След това заменете кода в src/index.js
файл с кода по-долу:
import 'dotenv/config'
import mongoose from 'mongoose';
import { ApolloServer } from 'apollo-server';
import { typeDefs } from './typeDefs';
import { resolvers } from './resolvers';
import { Movie as MovieModel } from './models/movie';
import Movies from './dataSources/movies';
const uri = process.env.MONGODB_URI
const main = async () => {
await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true })
};
main()
.then(console.log('🎉 connected to database successfully'))
.catch(error => console.error(error));
const dataSources = () => ({
movies: new Movies(MovieModel),
});
const server = new ApolloServer({ typeDefs, resolvers, dataSources })
server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Актуализираният код по-горе импортира Movie
модел и Movies
клас източник на данни в src/index.js
файл. След свързване към базата данни MongoDB, dataSources
се създава функция. Тази функция връща обект, съдържащ екземпляр на Movies
източник на данни, който получава Movie
модел като параметър. dataSources
след това функцията се предава на екземпляра на Apollo Server, правейки Movies
екземпляр на източник на данни, наличен във всяка функция на преобразувател.
За да замените твърдо кодирания източник на данни с Movie
източник на данни, заменете кода в src/resolvers.js
файл с кода по-долу:
export const resolvers = {
Query: {
getMovies: async (_, _args, { dataSources: { movies } }) => {
return movies.getMovies();
},
getMovie: async (_, { id }, { dataSources: { movies } }) => {
return movies.getMovie(id);
}
},
Mutation: {
createMovie: async (_, args, { dataSources: { movies } }) => {
return movies.createMovie(args)
}
}
}
В актуализирания код по-горе, Movies
екземпляр на източника на данни се предава на Apollo Server в src/index.js
файлът е достъпен във функциите на преобразувателя чрез dataSources
свойство на споделения контекстен обект. Всяка функция на преобразувател извиква съответния метод в източника на данни, за да извърши посочената операция в базата данни MongoDB.
Всяка заявка, направена в този момент, ще върне празен резултат, тъй като базата данни MongoDB в момента е празна. Рестартирайте сървъра си, след което посетете акаунта си в Mongo Atlas във вашия браузър. На вашата страница „Разгръщане на база данни“ на MongoDB изберете своя клъстер от база данни и щракнете върху раздела „Колекции“. В раздела „Колекции“ щракнете върху бутона „Вмъкнете ДОКУМЕНТ“ и добавете толкова филмови документи, колкото искате.
Във вашия пясъчна среда на Apollo Server стартирайте ExampleQuery
от предишния раздел. Трябва да получите списък с всички филмови документи във вашата колекция Mongo DB. В този раздел сте използвали вашата база данни MongoDB като източник на данни за вашия GraphQL сървър. В следващия раздел ще разположите своя GraphQL сървър онлайн на Koyeb.
Разгръщане в Koyeb
Първата стъпка към внедряването на GraphQL сървъра на Koyeb е добавянето на npm скриптове, необходими за изграждане на кода в производството. Добавете следните скриптове по-долу към вашия package.json
файл:
"scripts": {
...
"prebuild": "rimraf dist && mkdir dist",
"build": "babel src -d dist",
"start": "node ./dist/index.js"
}
Трите npm скрипта, добавени по-горе, включват:
prebuild
скрипт, за да се уверите, че има празенdist
директория предиbuild
скриптът се изпълнява.build
скрипт, който транспилира целия код вsrc
директория към синтаксиса на JavaScript ES5 вdist
директория с помощта наbabel
пакет.start
скрипт, който стартира сървъра.
След това създайте GitHub хранилище за вашия GraphQL сървър, след което изпълнете командите по-долу в прозореца на вашия терминал:
git add --all
git commit -m "Complete GraphQL server with MongoDB data source."
git remote add origin [email protected]<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
git branch -M main
git push -u origin main
От контролния панел на Koyeb отидете на Secrets
раздел и създайте нова тайна. Въведете MONGODB_URI
като тайно име и вашия низ за връзка с MongoDB като стойност. След това отидете на Overview
раздел и щракнете върху бутона „Създаване на приложение“, за да започнете процеса на създаване на приложението.
На страницата за създаване на приложение:
- Изберете GitHub като метод за внедряване.
- В падащото меню хранилища изберете хранилището на GitHub за вашия код.
- Изберете клона, който искате да разгърнете. напр.
main
. - В секцията променливи на средата щракнете върху бутона за добавяне на променлива на средата.
- Изберете
Secret
въведетеMONGODB_URI
като ключ и изберетеMONGODB_URI
тайна, създадена по-рано като стойност. - Добавете променлива на средата в обикновен текст с ключа
PORT
и стойност8080
. - Дайте име на приложението си. напр.
graphql-apollo-server
и щракнете върху бутона „Създаване на приложение“.
Докато създавате приложението, run
и build
командните опции бяха пропуснати, тъй като платформата Koyeb може да открие build
и start
скриптове в package.json
файл и ги изпълнете автоматично. Щракването върху бутона „Създаване на приложение“ ви пренасочва към страницата за внедряване, където можете да наблюдавате процеса на внедряване на приложението. След като внедряването приключи и всички необходими здравни проверки преминат, можете да получите достъп до публичния си URL адрес.
Тествайте своя GraphQL API
Използвайки любимия си инструмент за тестване на API или тази онлайн игра на GraphiQL, направете getMovies
GraphQL заявка към вашия публичен URL адрес. Трябва да получите отговор на всички филмови документи във вашата база данни MongoDB.
Заключение
Това е! Успешно създадохте и разположихте GraphQL сървър с Apollo Server и източник на данни MongoDB в Koyeb. Чувствайте се свободни да добавите още заявки и мутации към вашия GraphQL сървър. Тъй като внедрихме в Koyeb, използвайки задвижвано от git разгръщане, нова компилация ще се задейства автоматично и ще бъде разгърната на Koyeb всеки път, когато натиснете промените си във вашето GitHub хранилище.
Промените ви ще станат активни веднага щом внедряването ви премине всички необходими здравни проверки. В случай на неуспех по време на внедряването, Koyeb поддържа най-новото работещо внедряване в производството, за да гарантира, че приложението ви винаги работи и работи.
Чрез внедряването на Koyeb нашето приложение се възползва от естественото глобално балансиране на натоварването, автоматично мащабиране, автоматично възстановяване и автоматично HTTPS (SSL) криптиране с нулева конфигурация от наша страна.
Ако искате да разгледате кода за демонстрационното приложение, можете да го намерите тук.