{
user(id: 1) {
name
birthday
}
SELECT name, birthday FROM users
WHERE id = 1;
A Query Language
For APIs
Client
Server
Relational Database
SQL
(API)
GraphQL
1. One URL
2. Post Method
1. Multiple URLs
2. Get, Post, Patch, Put, Delete, ...
Rest
https://www.howtographql.com/basics/1-graphql-is-the-better-rest/
GraphQL
https://www.howtographql.com/basics/1-graphql-is-the-better-rest/
import { ApolloServer } from 'apollo-server';
const typeDefs = ...;
const resolvers = ...;
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen({ port: 3000 });
server.js
type User {
name: String!
age: Int
}
type Article {
authors: [User]
title: String
content: String
}
Int
Float
String
Boolean
ID
(Default) Scalar Types
Object Types
Array
Non-Null
type User {
id: ID
name: String
}
type Query {
me: User!
}
~ Get
~ Post, Put, Patch, Delete
{
query: Query
mutation: Mutation
subscription: Subscription
}
import { gql, ApolloServer } from 'apollo-server';
const typeDefs = gql`
type User {
id: ID
name: String
}
type Query {
me: User
}
`;
const server = new ApolloServer({
typeDefs,
});
server.listen({ port: 3000 });
Schema Definition Language (SDL)
import { gql, ApolloServer } from 'apollo-server';
const typeDefs = gql`
type User {
id: ID
name: String
}
type Query {
me: User
}
`;
const resolvers = {
User: {
id: () => '1',
name: () => '名字',
},
Query: {
me: () => ({}),
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen({ port: 3000 });
query {
me {
id
name
}
}
{
"data": {
"me": {
"id": 1,
"name": "名字"
}
}
}
import { gql, ApolloServer } from 'apollo-server';
const typeDefs = gql`
type User {
id: ID
name: String
}
type Query {
me: User
}
`;
const resolvers = {
User: {},
Query: {
me: () => ({
id: '1',
name: '名字',
}),
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen({ port: 3000 });
query {
me {
id
name
}
}
{
"data": {
"me": {
"id": 1,
"name": "名字"
}
}
}
query {
me {
id
name
}
}
( 1 ) user = meResolver()
( 2 ) id = idResolver ? idResolver() : user.id
( 2 ) name = nameResolver ? nameResolver() : user.name
1. 會幫你設 default resolver
2. default resolver 看得到上一層 resolver 返回的 Object
有點像這樣:
function resolver(parent, args, context, info) {
...
}
parent: 上一層 resolver 返回的 object
args: 這個 field 本身接受的參數
context: 通常包含這個 HTTP request 的一些訊息例如 header 的內容
info: 包含整個 schema、這次 graphql 查詢的全部內容、現在在哪個位置
https://www.prisma.io/blog/graphql-server-basics-the-schema-ac5e2950214e/
function User(options) {
this.id = options.id;
this.name = options.name;
}
User.prototype.getRecommendedProducts = function ...
const typeDefs = gql`
type Product {
id: ID
name: String
}
type User {
id: ID
name: String
recomendedProducts: [Product]
}
type Query {
me: User
}
`;
const resolvers = {
User: {
recommendedProducts: user => user.getRecommendedProducts(),
},
Query: {
me: () => {
const user = ...
return user;
},
},
};
// Not lazy var value = 1 + 1 // immediately evaluates to 2 // Lazy var lazyValue = () => 1 + 1 // Evaluates to 2 when lazyValue is *invoked*
default resolver 像:
const resolver = (parent, args, context, info) => {
if ( typeof parent.field === 'function') {
return parent.field(args, context, info);
}
return parent.field;
}
function User(options) {
this.id = options.id;
this.name = options.name;
}
User.prototype.recommendedProducts = function ...
const typeDefs = gql`
type Product {
id: ID
name: String
}
type User {
id: ID
name: String
recomendedProducts: [Product]
}
type Query {
me: User
}
`;
const resolvers = {
User: {},
Query: {
me: () => {
const user = ...
return user;
},
},
};
type User {
id: ID
name: String
friends: [User]
books: [Book]
}
type Book {
id: ID
title: String
authors: [User]
}
query {
me {
friends {
friends {
books {
authors {
friends {
id
name
}
}
}
}
}
}
}
type User {
id: ID
name: String
friends: [User]
books: [Book]
}
type Book {
id: ID
title: String
authors: [User]
}