GraphQL — с чего начать?
Павел Шалаев (@lawrentiy)
ноябрь 2017
1. Мероприятие
- Дата
- Время
- Название
- Список участников
- Создатель
2. Пользователь
- Имя
- Роль
3. Роль пользователя:
- админ
- простой пользователь
Схема
Schemas and Types
Type
Fields
Arguments
Scalar types
Enumeration
Lists
Interfaces
Union types
Input types
GraphQL
GraphQL - язык или синтаксис (кому как удобнее).
Позволяет клиенту точно указать, какие данные ему нужны.
Облегчает агрегацию данных из нескольких источников.
Использует систему типов для описания данных.
Построен на трёх основных строительных блоках:
схемaх (schema),
запросах (queries)
решателях (resolvers).
Поддерживают вложенные поля.
Cхема запроса GraphQL и структура базы данных никак не связаны
https://habrahabr.ru/post/326986/
query getMyPost($id: String) {
post(id: $id){
title
body
author{
name
avatarUrl
profileUrl
}
}
}
Query: {
post(root, args) {
return Posts.find({ id: args.id });
}
},
Post: {
author(post) {
return Users.find({ id: post.authorId})
}
}
const typeDefs = `
type Author {
id: Int!
firstName: String
lastName: String
posts: [Post] # the list of Posts by this author
}
type Post {
id: Int!
title: String
author: Author
votes: Int
}
# the schema allows the following query:
type Query {
posts: [Post]
author(id: Int!): Author
}
# this schema allows the following mutation:
type Mutation {
upvotePost (
postId: Int!
): Post
}
`;
Query
Resolvers
Schema
create-react-app
+
apollo-client
react-apollo
graphql
graphql-tag
Запрос
Мутация
Query
Fields
Arguments
Aliases
Fragments
Variables
Directives
Mutations
Inline Fragments
Meta fields
Subscriptions
import * as React from 'react' import { render } from 'react-dom' import ApolloClient from 'apollo-client' import { HttpLink, InMemoryCache } from 'apollo-client-preset' import { ApolloProvider } from 'react-apollo' import EventsList from './events/EventsList' import NewEvent from './events/NewEvent' import CreateUser from './events/CreateUser' // Apollo client const client = new ApolloClient({ link: new HttpLink({ uri: 'https://api.graph.cool/simple/v1/cja2s8bhwac2c0104via9triy' }), cache: new InMemoryCache().restore({}) }); const ApolloApp = ( <ApolloProvider client={client}> <div> <NewEvent /> <CreateUser /> <EventsList /> </div> </ApolloProvider> ); render(ApolloApp, document.getElementById('root'));
import * as React from 'react' import { render } from 'react-dom' import { graphql } from 'react-apollo' import gql from 'graphql-tag' const eventItem = (item) => { return <div key={item.id}> <b>{item.name}</b> <div>{item.users.map(({ name }) => name).join(', ')}</div> </div> }; const EventsList = (props) => { const { data } = props; const { loading, items } = data; // Loading if (loading) return <div>loading...</div>; // Loaded return <div> {items.map(eventItem)} </div> }; export const MEETUPS_LIST = gql` query { items: allMeetups { id name users { displayName } } } `; export default graphql(MEETUPS_LIST)(EventsList);
import * as React from 'react' import { render } from 'react-dom' import { graphql, compose } from 'react-apollo' import gql from 'graphql-tag' import {MEETUPS_LIST} from './EventsList' const NewEvent = (props) => { const {mutate} = props; const handleKeyUp = (evt) => { if (evt.keyCode === 13) { mutate({ variables: { name: evt.target.value }, optimisticResponse: { create: { users: [{}], name: evt.target.value, id: Math.round(Math.random() * -1000000), __typename: 'Meetup', }, }, update: (store, { data: {createMeetup} }) => { // Read the data from the cache for this query. const data = store.readQuery({ query: MEETUPS_LIST }); // Add our channel from the mutation to the end. data.items.push(createMeetup); // Write the data back to the cache. store.writeQuery({ query: MEETUPS_LIST, data }); }, }); evt.target.value = ''; } }; return ( <input type="text" placeholder="new event" onKeyUp={handleKeyUp} /> ); }; const ADD_EVENT = gql` mutation createMeetup($name: String!) { createMeetup(name: $name) { id name } } `; const USER = gql` query user { user { id displayName } } `; export default compose( graphql(ADD_EVENT, { name: 'createMeetup' }), graphql(USER, { name: 'user' }), )(NewEvent);
{ "name": "krdf", "version": "0.1.0", "private": true, "dependencies": { "apollo-client": "^2.0.3", "apollo-client-preset": "^1.0.3", "apollo-test-utils": "^0.3.2", "graphql": "^0.11.7", "graphql-tag": "^2.5.0", "graphql-tools": "^2.7.2", "react": "^16.1.1", "react-apollo": "^2.0.1", "react-dom": "^16.1.1", "react-scripts": "1.0.17", "subscriptions-transport-ws": "^0.9.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" } }
Resolvers
Но это совсем другая история....
Query: {
post(root, args) {
return Posts.find({ id: args.id });
}
},
Post: {
author(post) {
return Users.find({ id: post.authorId})
}
}
GraphQL — с чего начать?
By lawrentiy
GraphQL — с чего начать?
Расскажу о своём опыте с GraphQL. Доклад для тех, кто хочет понять что такое GlaphQL, стоит ли его использовать и в каких проектах. Доклад не претендует на супер-уникальность, но с помощью живого общения вместе попробуем разобраться с этим модным пушным зверем
- 1,973