我现在来总结一下GraphQL

首先

由于阅读了有关GraphQL的O’Reilly书籍,以及在业余时间涉猎了AppSync,所以现在为了公司内部的学习会议,我总结了一下关于GraphQL的内容。


GraphQL是一种查询语言。

GraphQL是一种用于Web API的查询和模式语言,可以简洁地描述客户端应用程序的数据模型和要求。它由Facebook的开发团队创建,目的是为了描述功能和要求。


查询语言和模式语言

以下是关于在这里处理的查询语言和模式语言的想法和描述。

    • クエリ言語

クライアントアプリがGraphQLサーバーにリクエストを送信するための構文

スキーマ言語

GraphQLサーバーのデータ型の集合を定義するための構文


GraphQL的定位

在应用程序开发中使用的GraphQL的形象。

GraphQLについて.jpg

GraphQL服务器所执行的实际操作

APIサーバーとの通信を行う

もしくは直接データベースの操作を行う

クエリ構文を解析する

解釈した構文に基づいて処理(リゾルバ)が実行される

GraphQLの動作.jpg

作为WEB API的查询功能

将要发送给GraphQL服务器的查询使用POST方法作为HTTP请求发送。以下是使用cURL的示例。

curl --location --request POST 'http://snowtooth.moonhighway.com/' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query {\r\n  allLifts {\r\n    name\r\n  }\r\n}","variables":{}}

如果要测试查询请求,可以使用类似GraphiQL、GraphQL Playground或者Postman中的GraphQL功能。


查询的类型

在客户端应用程序中使用的查询语法中,可以使用三种操作。

    1. 查询

 

    1. 变更

 

    订阅

查询

用于获取数据的操作。在字段中指定实际要获取的数据。以下是一个通过Snootooth来获取所有缆车的名称和状态信息的示例。

query getAllLifts {
  allLifts {
    name
    status
  }
}

突变

负责数据写入操作。基本上语法与查询相同。以下是使用前一页的Snowtooth更新某个Lift状态的示例。

mutation openLift {
  setLiftStatus(id:"astra-express" status: OPEN) {
    name
    status
  }
}

订阅

可以从服务器实时接收数据。例如,为了每次接收到通过mutation更新的状态,不需要每次都发起查询,可以使用订阅功能,通过WebSocket实时接收数据。以下是该语法的一个示例。

可以用以下语法实现每次都查询不成功。

subscription listenStatusChange {
  liftStatusChange {
    name
    status
  }
}

这里省略了对话。

    • フラグメント

冗長な構文を共通化させる仕組み

ユニオン型

2つの異なるオブジェクト型をまとめる仕組み

インタフェース

実装すべきフィールドのリストを指定する抽象型


构建模式

為了實施GraphQL伺服器,首先需要設計一個資料類型的集合,也就是一個架構。可以參考以往文章中的實例來進行設計。

enum Category {
    HOGEHOGE
    HUGAHUGA
}

type Item {
    id: String!
    data: String!
    category: Category!
}

type Query {
    allItem: [Item]
    allItemOnCategory(category: Category): [Item]
}

input ItemInput {
    data: String!
    category: Category!
}

type Mutation {
    addItem(item: ItemInput!): Item
}

模样

类型是模式的核心。每种类型都对应一个字段。查询和变更也分别是类型中定义的可用作字段的查询和变更。

type Item {
    id: String!
    data: String!
    category: Category!
}

type Query {
    allItem: [Item]
    allItemOnCategory(category: Category): [Item]
}

type Mutation {
    addItem(item: ItemInput!): Item
}

标量类型和列表

每个字段都具有特定类型的数据,这些内置类型称为标量类型。例如,id字段的标量类型被定义为String。顺便提一下,通过添加String!和!可以表示该字段不会为空。

此外,通过使用[]将类型括起来,可以指定字段为类型的列表。例如,[Item]表示一个类型为Item的列表。


枚举

当我们想要在字段中定义只有有限选项的字符串输入和输出时,可以使用枚举( Enum )。

enum Category {
    HOGEHOGE
    HUGAHUGA
}

在这里创建的Category可作为字段类型使用。


输入式

用于参数的类型。用于将多个参数组合在一起。

input ItemInput {
    data: String!
    category: Category!
}

在这里创建的ItemInput只能用作参数。


在这里省略的故事

    • カスタムスカラー型

独自で定義されたスカラー型。

ユニオン型

複数の型のうち一つを返す型。

インタフェース

型の中で必ず存在するフィールドを定義する抽象型。


解决者

解析器是返回特定字段的函数。它会针对在查询中指定的字段进行查询。以下是我在以往的文章中写的有关AppSync和CDK实现的示例。

...
    itemDS.createResolver({
      typeName: 'Query',
      fieldName: 'allItem',
      requestMappingTemplate: MappingTemplate.dynamoDbScanTable(),
      responseMappingTemplate: MappingTemplate.dynamoDbResultList(),
    })
    itemDS.createResolver({
      typeName: 'Mutation',
      fieldName: 'addItem',
      requestMappingTemplate: MappingTemplate.dynamoDbPutItem(
          PrimaryKey.partition('id').auto(),
          Values.projecting('item')),
      responseMappingTemplate: MappingTemplate.dynamoDbResultItem(),
    })
...

从直觉的角度来看,解析器是用于将请求和响应主体进行映射和内部处理的实现机制。


最后

    • GraphQLを用いた開発では、スキーマとクエリの2つの言語を書くことになる

スキーマはAPIの仕様となるもの
クエリはクライアントアプリからのリクエスト

基本的にライブラリを用いた開発となる

手で実装するのはおそらく難解
GraphQL用のライブラリについては公式ページで紹介されている。


介绍了与GraphQL相关的问题和文章的链接。


N+1问题

N+1问题指的是在一个SQL中获取N个记录后,为了分别获取与每个记录相关联的记录而发出N个SQL的问题。当在GraphQL的解析器中使用SQL时,这个问题很容易引发。这篇文章对这个问题很有参考价值。


有没有技术可以替代REST API?

正如这篇文章所提到的那样,GraphQL也有其缺点。

    • フルスクラッチでの実装が難しい(基本はライブラリ依存)

 

    画像や動画などの大容量バイナリの扱いが難しい(JSONなので)

Redux对决GraphQL

这个话题在某个幻灯片的第28页表格上有明确而简明易懂的总结。
像这样的文章通常会对Apollo Client和Redux进行对比并展开讨论,正如某些文章所述。

GraphQL是一项在2015年发布的规范。
广告
将在 10 秒后关闭
bannerAds