Подпишитесь на новостную рассылку чтобы не пропустить вышедшие статьи
-diff --git a/content/articles/2020-09-24_ispolzovanie-apollo-server-vmeste-s-typescript.md b/content/articles/2020-09-24_ispolzovanie-apollo-server-vmeste-s-typescript.md
index 76bd060..3812e94 100644
--- a/content/articles/2020-09-24_ispolzovanie-apollo-server-vmeste-s-typescript.md
+++ b/content/articles/2020-09-24_ispolzovanie-apollo-server-vmeste-s-typescript.md
@@ -25,14 +25,14 @@ tags:
## Содержание
-* [Описание списка зависимостей](#Описание-списка-зависимостей)
-* [Структура проекта](#Структура-проекта)
-* [Предварительная настройка](#Предварительная-настройка)
-* [Создание Type Definitions](#Создание-Type-Definitions)
-* [Создание Resolvers](#Создание-Resolvers)
-* [Создание схемы](#Создание-схемы)
-* [Использование Apollo Server Express](#Использование-Apollo-Server-Express)
-* [Заключение](#Заключение)
+- [Описание списка зависимостей](#Описание-списка-зависимостей)
+- [Структура проекта](#Структура-проекта)
+- [Предварительная настройка](#Предварительная-настройка)
+- [Создание Type Definitions](#Создание-Type-Definitions)
+- [Создание Resolvers](#Создание-Resolvers)
+- [Создание схемы](#Создание-схемы)
+- [Использование Apollo Server Express](#Использование-Apollo-Server-Express)
+- [Заключение](#Заключение)
💡 Данное руководство расчитано на тех разработчиков, кто уже имел небольшой опыт с использованием технологий **Apollo Server** и **TypeScript**.
@@ -40,44 +40,48 @@ tags:
Для установки необходимых npm пакетов используйте команды ниже, но перед этим создайте папку проекта с любым названием и инициализируйте npm вместе с [конфигом typescript](https://www.typescriptlang.org/docs/handbook/compiler-options.html):
-```bash
+```bash
mkdir typescript-apollo-server
cd ./typescript-apollo-server
// инициализация npm
-npm init -y
+npm init -y
// установка dev зависимостей
npm install -D @types/node prettier ts-node ts-node-dev typescript
// установка основных зависимостей
-npm install @types/graphql-depth-limit apollo-server-express cors dotenv express graphql graphql-depth-limit graphql-tools
+npm install @types/graphql-depth-limit apollo-server-express cors dotenv express graphql graphql-depth-limit graphql-tools
// инициализировать файл с настройками typescript
npx tsc --init
```
+
Теперь по порядку узнаем для чего нужны эти пакеты:
**devDependencies:**
+
1. **@typesnode** - устанавливаем type definitions node.js для нашего typescript **~717 kB**
2. **prettier** - этот пакет нужен для форматирования вашего кода, вы можете установить его по желанию **~9.08 MB**
3. **ts-node** - данные пакет предназначен для транспиляции typescript кода в javascript **~377 kB**
-4. **ts-node-dev** - отладка кода typescript. этот пакет будет следить за вашими файлами **.ts** и перезагружать сервер при их изменении (можно использовать nodemon) **~57 kB**
+4. **ts-node-dev** - отладка кода typescript. этот пакет будет следить за вашими файлами **.ts** и перезагружать сервер при их изменении (можно использовать nodemon) **~57 kB**
5. **typescript** - сам typescript **~56.8 MB**
**dependencies:**
+
1. **apollo-server-express** - GraphQL сервер вместе в веб-фреймворком Express.js **~70.1 kB**
2. **express** - веб-фреймворк Express.js **~208 kB**
3. **graphql** - среда выполнения запросов к нашей API **~1.92 MB**
4. **graphql-depth-limit** - защита он неограниченных запросов в API, подробнее [здесь](https://www.apollographql.com/blog/securing-your-graphql-api-from-malicious-queries-16130a324a6b/)
5. **@types/graphql-depth-limit** - type definitions graphql-depth-limit
-6. **graphql-tools** - пакет, который будет создавать нашу GraphQL схему **~18 kB**
+6. **graphql-tools** - пакет, который будет создавать нашу GraphQL схему **~18 kB**
7. **dotenv** - пакет, который будет загружать переменные среды из файла **.env** в **process.env** - **~23.1 kB**
8. **cors** - для включения кросс доменных запросов - **~20 kB**
## Структура проекта
Теперь после того как все пакеты установлены, определимся со структурой проекта:
+
```text
.
└── typescript-apollo-server
@@ -103,13 +107,16 @@ npx tsc --init
## Предварительная настройка
Перед тем как начать разрабатывать наш сервер, зайдем в **package.json** и установим скрипты запуска:
+
```text
"scripts": {
"start": "ts-node index.ts",
"server": "ts-node-dev --respawn index.ts"
},
```
+
Теперь необходимо создать схему, создаем папку **graphql** и в ней также создаем еще две папки **resolvers** и **typeDefs**, также не забываем создать файл **schema.ts**:
+
```bash
mkdir graphql
cd ./graphql
@@ -134,6 +141,7 @@ touch Book.graphql
Далее напишем наши типы. Обратите внимание что для удобства и разделения кода мы будем использовать импорты. Возможность использовать импорты нам предоставляет пакет **graphql-tools**. Для того чтобы импортировать файл **.graphql** ставится знак **#** и указывается путь.
Главный файл **schema.graphql**:
+
```graphql
# ./graphql/typeDefs/schema.graphql
@@ -147,6 +155,7 @@ type Query {
```
Файл **Book.graphql**:
+
```graphql
# ./graphql/typeDefs/Book.graphql
@@ -157,6 +166,7 @@ type Book {
```
Файл **User.graphql**:
+
```graphql
# ./graphql/typeDefs/User.graphql
@@ -191,10 +201,11 @@ cd ..
Наконец прописываем обработчики:
Файл **Books.ts**:
+
```js
// ./graphql/resolvers/Books/Books.ts
-import { IResolvers } from 'graphql-tools';
+import { IResolvers } from "graphql-tools"
interface BookType {
id: string;
@@ -202,17 +213,17 @@ interface BookType {
}
const books = [
- { id: '1', title: 'First Book' },
- { id: '2', title: 'Second Book' },
-];
+ { id: "1", title: "First Book" },
+ { id: "2", title: "Second Book" },
+]
const booksResolver: IResolvers = {
Query: {
books: (): BookType[] => books,
},
-};
+}
-export default booksResolver;
+export default booksResolver
```
Файл **Users.ts**:
@@ -220,7 +231,7 @@ export default booksResolver;
```js
// ./graphql/resolvers/Users/Users.ts
-import { IResolvers } from 'graphql-tools';
+import { IResolvers } from "graphql-tools"
interface UserType {
id: string;
@@ -228,17 +239,17 @@ interface UserType {
}
const users = [
- { id: '1', name: 'John' },
- { id: '2', name: 'Ivan' },
-];
+ { id: "1", name: "John" },
+ { id: "2", name: "Ivan" },
+]
const usersResolver: IResolvers = {
Query: {
users: (): UserType[] => users,
},
-};
+}
-export default usersResolver;
+export default usersResolver
```
Резолверы получились довольно простые и понятные, теперь нужно собрать их в один массив для дальнейшего экспорта. В файле **index.ts** прописываем следующее:
@@ -246,18 +257,19 @@ export default usersResolver;
```js
// ./graphql/resolvers/index.ts
-import { IResolvers } from 'graphql-tools';
+import { IResolvers } from "graphql-tools"
-import booksResolver from './Books/Books';
-import usersResolver from './Users/Users'
+import booksResolver from "./Books/Books"
+import usersResolver from "./Users/Users"
-const resolvers: IResolvers[] = [usersResolver, booksResolver];
+const resolvers: IResolvers[] = [usersResolver, booksResolver]
-export default resolvers;
+export default resolvers
```
## Создание схемы
-Как говорилось ранее, пакет **graphql-tools** предназначен для создания схемы. Теперь перейдем в наш файл **schema.ts** и соберем нашу схему.
+
+Как говорилось ранее, пакет **graphql-tools** предназначен для создания схемы. Теперь перейдем в наш файл **schema.ts** и соберем нашу схему.
Раньше для того чтобы работали наши graphql импорты мы применяли пакет **graphql-import**, но теперь его не нужно устанавливать так как он уже входит в состав **graphql-tools**. Подробнее об этом можно прочитать [здесь](https://www.graphql-tools.com/docs/migration-from-import).
С помощью функций **loadSchemaSync**, **loadFilesSync**, и **addResolversToSchema** мы собираем нашу схему. Функция **mergeResolvers** предназначена для объединения наших резолверов. Подробнее о "**Resolvers merging**" [здесь](https://www.graphql-tools.com/docs/merge-resolvers/). Далее всё что нам остается сделать - это экспортировать нашу схему и написать сервер.
@@ -265,20 +277,26 @@ export default resolvers;
```js
// ./graphql/schema.ts
-import { mergeResolvers, loadSchemaSync, loadFilesSync, GraphQLFileLoader, addResolversToSchema } from 'graphql-tools';
-import { GraphQLSchema } from 'graphql';
+import {
+ mergeResolvers,
+ loadSchemaSync,
+ loadFilesSync,
+ GraphQLFileLoader,
+ addResolversToSchema,
+} from "graphql-tools"
+import { GraphQLSchema } from "graphql"
const schema = loadSchemaSync(`${__dirname}/typeDefs/schema.graphql`, {
loaders: [new GraphQLFileLoader()],
-});
+})
-const resolvers = loadFilesSync(`${__dirname}/resolvers`);
+const resolvers = loadFilesSync(`${__dirname}/resolvers`)
const schemaWithResolvers: GraphQLSchema = addResolversToSchema({
schema,
resolvers: mergeResolvers(resolvers),
-});
+})
-export default schemaWithResolvers;
+export default schemaWithResolvers
```
## Использование Apollo Server Express
@@ -294,38 +312,38 @@ touch index.ts
```js
// ./index.ts
-import express, { Application, Request, Response } from 'express';
-import cors from 'cors';
-import depthLimit from 'graphql-depth-limit';
-import { ApolloServer } from 'apollo-server-express';
-import schema from './graphql/schema';
+import express, { Application, Request, Response } from "express"
+import cors from "cors"
+import depthLimit from "graphql-depth-limit"
+import { ApolloServer } from "apollo-server-express"
+import schema from "./graphql/schema"
-const PORT = process.env.PORT || 4000;
+const PORT = process.env.PORT || 4000
const startServer = (): void => {
try {
- const app: Application = express();
+ const app: Application = express()
const server: ApolloServer = new ApolloServer({
schema,
validationRules: [depthLimit(10)], // выставляем правило deph limit = 10
playground: true,
- });
+ })
- app.use('*', cors());
- app.get('/', (req: Request, res: Response) => res.send('GraphQL API'));
+ app.use("*", cors())
+ app.get("/", (req: Request, res: Response) => res.send("GraphQL API"))
- server.applyMiddleware({ app });
+ server.applyMiddleware({ app })
app.listen({ port: PORT }, () =>
console.log(`🚀 Server ready on port: ${PORT}`)
- );
+ )
} catch (err) {
- console.log(`❌ Something went wrong: \n ${err}`);
+ console.log(`❌ Something went wrong: \n ${err}`)
}
-};
+}
-startServer();
+startServer()
```
Как видим, ничего сложного нет, просто применяем функцию [applyMiddleware](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#applymiddleware) для того чтобы соедениеть Apollo Server с фрэймворком Express.js. Далее можно протестировать наш сервер, запускаем команду **npm run start** и переходим по адресу **/graphql**. Для тестирования можно выполнить вот такой запрос:
@@ -372,7 +390,6 @@ startServer();
}
```
-
## Заключение
-Как видим, использование Apollo Server вместе с TypeScript оказалась совсем не сложной задачей, так как и Apollo Server и пакет graphql-import имеют поддержку typescript из коробки.
\ No newline at end of file
+Как видим, использование Apollo Server вместе с TypeScript оказалась совсем не сложной задачей, так как и Apollo Server и пакет graphql-import имеют поддержку typescript из коробки.
diff --git a/gatsby-browser.js b/gatsby-browser.js
index 1114378..1913a1a 100644
--- a/gatsby-browser.js
+++ b/gatsby-browser.js
@@ -3,7 +3,7 @@ import React from "react"
import Layout from "./src/components/Layout/Layout"
import "prismjs/themes/prism-tomorrow.css"
-import 'prismjs/plugins/line-numbers/prism-line-numbers.css'
+import "prismjs/plugins/line-numbers/prism-line-numbers.css"
import "./src/styles/global.scss"
import "./src/components/Header/Header.scss"
@@ -30,8 +30,12 @@ export const shouldUpdateScroll = ({ routerProps: { location } }) => {
}
export const wrapPageElement = ({ element, props }) => {
- const { location: { pathname } } = props
- pathname.includes('/amp/article/') && props.pageContext.slug ? props.amp = true : props.amp = false
+ const {
+ location: { pathname },
+ } = props
+ pathname.includes("/amp/article/") && props.pageContext.slug
+ ? (props.amp = true)
+ : (props.amp = false)
return
Подпишитесь на новостную рассылку чтобы не пропустить вышедшие статьи
-