Ivan Asmer пре 6 година
родитељ
комит
76c5687077
1 измењених фајлова са 187 додато и 0 уклоњено
  1. 187 0
      graphql.md

+ 187 - 0
graphql.md

@@ -0,0 +1,187 @@
+GraphQL
+==========
+
+**[GraphQL](https://graphql.org/)** - слой приложения, который обеспечивает
+удобный язык запросов к бэку.
+
+**GraphQL** используется:
+-   На **backend** для того, что бы запустить тот или иной код для сбора данных.
+    Обычно это запросы к СУБД через **Sequelize** или **Mongoose**. 
+-   На **frontend** для того, что бы сделать запрос к **backend**.
+
+
+Таким образом **GraphQL** берет на себя передачу данных с бэка на фронт
+(**AJAX**)
+
+
+GraphQL minimal
+----
+
+###  Устанавка
+
+```bash
+npm install --save express-graphql graphql`
+```
+
+### Подключение
+
+```javascript
+const express_graphql = require('express-graphql');
+const { buildSchema } = require('graphql');
+```
+
+### Схема.
+
+По аналогии с **Sequelize** и **Mongoose** вы указываете **схему** - структуру
+ваших данных. Если в **ORM** и **ODM** это делается с помощью ассоциативных 
+массивов, то в **GraphQL** используется специальный язык:
+
+```javascript
+var schema = buildSchema(`
+    type Query {
+        getPost(id: String!): Post
+        getPosts: [Post]
+        getComments(id: Int!): [Comment]
+        getSubComments(id: Int!): [Comment]
+    }
+    type Mutation {
+        createPost(title: String!, text: String!): Post
+        createComment(postID: Int!, text: String!): Post
+    }
+
+    type Post {
+        id: Int
+        title: String
+        text:  String
+        age:   String
+        tagz:  [String]
+        comments: [Comment]
+        timestamp: Int
+        key: String
+    }
+    type Comment {
+        id: Int
+        text:  String
+        age:   String
+        commentId: Int
+    }
+`);
+```
+
+В примере выше:
+    - `type Query` (запрос) отвечает за виды запросов, которые вы можете посылать с
+        фронта. В данном случае реализовано четыре вида запросов:
+        - `getPost` - один пост из СУБД. 
+        - `getPosts` - лента постов
+        - `getComments` - комментарии верхнего уровня 
+        - `getSubComments` - комментарии к комментариям
+    - `type Mutation` (мутация) отвечает за запросы _на изменение_ данных:
+        - `createPost`
+        - `createComment`
+    - `type Post` описывает структуру поста, она во многом повторяет схему для **ORM**/**ODM**
+    - `type Comment` описывает структуру поста, она во многом повторяет схему для **ORM**/**ODM**
+
+#### Типы данных
+
+С примитивами все достаточно грустно, `String` и `Int`. Массивы декларируются c помощью
+`[]`
+
+### Резолверы
+
+**Резолверами** в **GraphQL** называют функции, которые запускаются движком **GraphQL** 
+для реализации тех или иных запросов или мутаций в реальной **CУБД**.
+
+Например, в простейшем виде:
+
+```javascript
+async function getPost({id}){
+   return await Post.findById(id)
+}
+
+async function getPosts({id}){
+   return await Post.findAll({})
+}
+```
+
+### Подключение **express-graphql** **middleware**
+
+При наличии схемы и резолверов остается отдать их в использование **GraphQL**
+и подключить **GraphQL** к **express** для обработки входящих запросов:
+
+```javascript
+var root = {
+    getPost,
+    getPosts,
+    getPostComments,
+    getSubComments,
+    createPost,
+    createComment,
+};
+
+
+
+// Create an express server and a GraphQL endpoint
+var app = express();
+app.use(cors())
+
+app.use('/graphql', express_graphql({
+    schema: schema,
+    rootValue: root,
+    graphiql: true
+}));
+```
+
+В примере выше:
+    -   `root` является корневым резолвером и отвечает за связь названий запросов и мутаций из схемы с резолверами
+    -   `app.use` используется для подключения GraphQL к express:
+        -   `schema` указывает на схему
+        -   `rootValue` - корневой резолвер
+        -   `graphiql` - ключ, который включает отладочный интерфейс GraphQL. он будет доступен по адресу /graphiql вашего бэка
+
+
+
+
+
+
+### Frontend
+Есть разные степени завязки **фронтэнда** на **GraphQL**, однако в простейшем случае достаточно небольшой библиотеки для взаимодействия с **бэкэндом**
+
+#### Установка
+
+```bash
+npm install --save graphql graphql-express
+```
+


+#### Подключение
+```javascript
+import { GraphQLClient } from 'graphql-request'
+
+const gql = new GraphQLClient("http://localhost:4000/graphql", { headers: {} })

+```
+
+



+Адрес должен соответствовать конфигурации **бэкэнда** - убедитесь что ваш **express** висит на нужном порту (4000 в примере) и что первый параметр в `app.use` (**endpoint**) верен.
+#### Запрос на бэкэнд
+
+```javascript
+gql.request(`query getPost($postID: String!){
+                      getPost(id:$postID){
+                            id
+                            title
+                            timestamp
+                            tagz
+                          }
+                        }`, {postID: this.props.match.params.id}) 
+    .then(data => store.dispatch({type: "DATA", data}))

+```
+


+Таким образом вы можете указывать, какие поля вам нужны или нет в результирующем запросе.
+### Отладка
+#### Backend
+`console.log` в резолвере позволит вам увидеть параметры запроса, сам факт запуска резолвера и, возможно, результат
+#### Frontend
+Текст запроса проще всего отладить в **GraphIQL** - тестовой консоли разработчика (доступна по ссылке `/graphiql` на вашем бэке). Потом копипастите его в код и далее **Developer Tools** и/или `console.log` в помощь.
+
+## Почитать
+-  [статья на хабре](https://habr.com/post/326986/)
+