我稍微了解了一下GraphQL
GraphQL术语
模式
-
- APIのこと。
-
- クライアントがサーバーにクエリを送信した時に、返却値として期待されるオブジェクトの型定義。
type キーワードによってGraphQLオブジェクトの型を定義する(その集合がSchema)。
以下の例において、 id, text, done, user, createTodo などを field(フィールド) と呼ぶ。
# graph/schema.graphqls
type Todo {
id: ID!
text: String!
done: Boolean!
user: User!
}
type User {
id: ID!
name: String!
}
type Query {
todos: [Todo!]!
}
input NewTodo {
text: String!
userId: String!
}
type Mutation {
createTodo(input: NewTodo!): Todo!
}
解决者
-
- フィールド(CreateTodo, etc)の実装。
-
- クライアントが要求したフィールドの値を返却するための関数。
フィールドをresolve(解決する)ので resolver。
// graph/schema.resolvers.go
func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) {
todo := &model.Todo{
Text: input.Text,
ID: fmt.Sprintf("T%d", rand.Int()),
User: &model.User{ID: input.UserID, Name: "user " + input.UserID},
UserID: input.UserID,
}
r.todos = append(r.todos, todo)
return todo, nil
}
func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, error) {
return &model.User{ID: obj.UserID, Name: "user " + obj.UserID}, nil
}
查询
-
- データの取得を行う言語。
-
- HTTP GETに相当。
- サーバーの schema で定義された「オブジェクトの型 type 」に、クライアントから取得可能な field が定義されている。
query findTodos {
todos {
text
done
user {
name
}
}
}
查询的响应
{
"data": {
"todos": [
{
"text": "todo",
"done": false,
"user": {
"name": "user 1"
}
}
]
}
}
突变
-
- データの作成・更新・削除を行う言語。
- HTTP POST/PUT/DELETEに相当。
mutation createTodo {
createTodo(input: { text: "todo", userId: "1" }) {
user {
id
}
text
done
}
}
突变的反应
{
"data": {
"createTodo": {
"user": {
"id": "1"
},
"text": "todo",
"done": false
}
}
}
数据来源(如果使用ApolloServer)
-
- ApolloServerが、DBやREST APIなどから取得したデータをカプセル化し、キャッシュやエラー処理を行えるようにするためのクラス。
接続先毎に作成する。
resolver から利用される。
Data sourceの例
RailsのREST APIのHTTPクライアント
ElasticSearchクライアント
DynamoDBクライアント
GraphQL和REST的比较
RESTGraphQL参照リクエスト(GET)クエリ(query)作成・更新・削除リクエスト(POST/PUT/DELETE)クエリ(mutation)Pub/Subなし
(WebSocketを使う場合が多い)クエリ(subscription)サーバの記述ルーティングとコントローラスキーマ(schema・type) / リゾルバ(resolver)
(WebSocketを使う場合が多い)クエリ(subscription)サーバの記述ルーティングとコントローラスキーマ(schema・type) / リゾルバ(resolver)
(エンドポイントは1つになるためルーティングの定義は最初の一回を除いて不要(なはず))
REST API的挑戰
-
- サーバーサイドでユースケース毎にAPIが増える。
- クライアントサイドでドメインロジックを作ったり、状態を持つ必要性が出る。
GraphQL的优势
-
- クライアントサイドとサーバーサイドのコミュニケーションコストの削減。
グラフ構造でリレーションを表現できるので、サーバーサイドはユースケース毎のAPIを作る必要がなくなり、クライアントサイドでそのまま表示できるようなクエリを作れば良い。(?)
クライアントサイドは利用可能な全ての状態がわかり、必要なデータを選択できる。
GraphQLクライアント(Appolo、Relayなど)を利用すると、グラフ構造をキャッシュしてくれる。これにより、
クライアントサイドは状態を持つ必要がなくなる。
GraphQL的缺点
-
- クエリのパフォーマンス問題や脆弱性を生みやすい。
- Securing Your GraphQL API from Malicious Queries
常见的误解
问:直接向客户端公开DB结构会有问题吗?
答:使用Hasura时,可以自动生成GraphQL模式从DB结构中,但这与REST相同。
请根据以下内容进行重新表述(仅需一种选择):
参考