狠狠撸

狠狠撸Share a Scribd company logo
インターフェース定義言語から学ぶ
モダンなWeb API方式
REST, GraphQL, gRPC
1
lagénorhynque?カマイルカ
(defprofile lagénorhynque
:id @lagenorhynque
:reading "/la?en????k/"
:aliases ["カマイルカ" "?"]
:languages [Java Clojure Haskell Python
日本語 English fran?ais русский]
:interests [プログラミング 語学/言語学 数学
法/政治 財務/会計]
:job-roles [エンジニアリングマネージャー
ソフトウェアアーキテクト]
:motto "楽しく楽にクールにスマートに"
2
私の仙台との接点
(仙台のイベント「タガヤス」ということで)
?は岐阜出身、千葉在住
2016年4月から (本社: 東京?市ヶ谷)
所属
2017年からオプトの「仙台ラボラトリ」メンバー
と合同で仕事することが増えた
2018年春、2023年春には仙台に出張する機会も
株式会社オプト
3
記事: サービス間連携のためのGraphQL APIをClojure
で開発している話
4
発表:
at
(2022-06-24)
JavaからScala、そしてClojureへ: 実務で活きる
関数型プログラミング
【タガヤスその26】初心者歓迎!関数型プログラ
ミングって何だろう? 5
Table of Contents
1. Web APIのスキーマ駆動開発
2. 現代の主要なWeb API方式
3. REST/GraphQL/gRPCのIDL
6
1. Web APIのスキーマ駆動開発
7
スキーマ駆動開発(schema-driven development)
Web APIのサーバとクライアントの間の「契約」で
あるスキーマ(schema)を先行して定義し、それを
起点に実装を進める開発スタイル
スキーマはインターフェース定義言語(inteface
definition/description language; IDL)で記述する
認識齟齬/不整合を避けて効率的に開発できる
コード/ドキュメント生成などの応用もしやすい
a.k.a. スキーマファースト開発(schema-first
development)
8
スキーマ駆動開発(サーバサイド)の基本的な流れ
1. APIの構想/方式設計
2. APIスキーマの(初期)設計
アウトプット: IDLファイル
3. [optional] プロジェクト/コードの自動生成
アウトプット: プロジェクトテンプレート/スタ
ブ/型定義コード
利用言語/ライブラリ/ツールに大きく依存する
4. APIサーバ実装/テスト? APIスキーマの拡張/修正
9
2. 現代の主要なWeb API方式
REST, GraphQL, gRPC
10
REST
schema
definition SDL (IDL)
data
format
(text),
etc.
(text),
etc.
(binary)
notes
(tools)
query
language (compiler)
HTTP/2
GraphQL gRPC
OpenAPI
Specification
GraphQL Protocol Buffers
JSON JSON Protocol Buffer
wire format
Swagger protoc
11
REST (representational state transfer)
本質: プロトコルに寄り添ったWeb APIの設計
パターン
具体的な形式は設計者によって揺れが大きい:
に基づいてYAML/JSON形式
でスキーマを記述できる(de facto standard?)
/ の各種ツールでスキーマ編集/
閲覧や動作確認、コード生成などができる
e.g. (ブラウザ版)
HTTP
Richardson Maturity Model
OpenAPI Specification
Swagger OpenAPI
Swagger Editor
12
13
GraphQL
本質: クライアントに自由度を与えるWebサービス
のクエリ言語
cf. RDBに対するSQL
(単純なREST APIで発生しやすい)オーバーフェッ
チング/アンダーフェッチングを回避できる
Schema Definition Language (SDL)でス
キーマを記述する
というブラウザIDEでAPIコールを試す
ことができる
e.g. GitHub GraphQL APIの
クライアントはGraphQLのクエリ言語を用いて必
要最小限のデータのみを選択的に取得できる
GraphQL
GraphiQL
Explorer
14
15
gRPC
本質: ベースの効率的なRPC (remote
procedure call)のためのフレームワーク
マイクロサービスアーキテクチャのバックエンド
サービス間連携で有力な選択肢
Webフロントエンド向けのAPIとしても利用でき
る:
のIDLでスキーマを記述する
(Protocol Buffers compiler)でサーバ/ク
ライアントのコード生成ができる
(バイナリ形式)でデー
タを送受信する
HTTP/2
grpc-web
Protocol Buffers
protoc
Protocol Buffer wire format
16
17
3. REST/GraphQL/gRPCのIDL
18
インターフェース定義言語(IDL)の記述
API style IDL
REST OpenAPI Specification (.yaml, .json)
GraphQL GraphQL SDL (.graphql)
gRPC Protocol Buffers (.proto)
19
題材: 蔵書/読書管理サービス
cf. ,
主な機能
カタログの書籍情報のCRUD
本棚(蔵書)の書籍の読書状況/レビュー情報の
CRUD
※サンプルコード:
ブクログ 読書メーター
web-api-style-comparison
20
[REST] データモデル(エンティティ)の定義例
components > schemas > Book: Book データ
のJSON仕様(cf. )
components:
schemas:
Book:
title: Book
type: object
properties:
id:
type: integer
description: 書籍ID
minimum: 0
readOnly: true
title:
type: string
description: 書名
# ...(以下略)...
JSON Schema
21
required: 必須のプロパティ
example: データ例
required:
- id
- title
- author
# ...(以下略)...
description: 書籍
example:
id: 1
title: Web APIの設計
author: '(著) Arnaud Lauret, (翻訳) 株式会社クイープ, (監
修) 株式会社クイープ'
publisher: 翔泳社
publication_date: '2020-08-26'
official_site_url: 'https://www.shoeisha.co.jp/book/
detail/9784798167015'
22
[REST] 参照系操作の定義例
paths > /books > get: パス/books に対する
GETリクエスト
paths:
/books:
get:
tags:
- book_catalog
summary: 書籍の一覧取得
operationId: get-books
description: 検索条件を満たす書籍をカタログから取得する。
23
parameters: パラメータの仕様
parameters:
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- schema:
type: string
minLength: 1
in: query
name: title
description: 書名 (部分一致)
- schema:
type: string
minLength: 1
in: query
# ...(以下略)...
24
responses > '200': レスポンスステータスコー
ド200の場合
content > application/json: レスポンス
ボディのJSON仕様
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Book'
pagination:
$ref: '#/components/schemas/Pagination'
# ...(以下略)...
25
[REST] 更新系操作の定義例
paths > /books > post: パス/books に対す
るPOSTリクエスト
paths:
/books:
post:
tags:
- book_catalog
summary: 書籍の追加
operationId: post-books
description: 書籍をカタログに追加する。
26
requestBody > content >
application/json: リクエストボディのJSON仕
様
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Book'
examples:
example-1:
value:
title: Web APIの設計
author: '(著) Arnaud Lauret, (翻訳) 株式会社
クイープ, (監修) 株式会社クイープ'
publisher: 翔泳社
publication_date: '2020-08-26'
# ...(以下略)...
description: 書籍
27
responses > '201': レスポンスステータスコー
ド201の場合
headers > Location: レスポンスのLocation
ヘッダーの仕様
responses:
'201':
description: Created
headers:
Location:
schema:
type: string
format: uri-reference
example: /books/1
description: 追加された書籍へのURL
28
[GraphQL] データモデル(エンティティ)の定義例
Bookデータのオブジェクト型定義
T! はNon-Null型(ただのT はnullable型)
"""書籍"""
type Book {
"""書籍ID"""
id: ID!
"""書名"""
title: String!
"""著者"""
author: String!
"""出版社"""
publisher: String!
"""出版年月日"""
# ...(中略)...
"""レビューの集計結果"""
reviewSummary: ReviewSummary!
}
29
ReviewSummary, Reviewデータのオブジェクト型
定義
[T] はList型([T!], [T]!, [T!]! もある)
"""レビューの集計結果"""
type ReviewSummary {
"""平均ランク"""
averageRank: Float
"""リスト"""
reviews: [Review!]!
}
"""レビュー"""
type Review {
"""ランク (星の数1?5)"""
rank: Int
"""コメント"""
comment: String
}
30
[GraphQL] 参照系操作の定義例
booksInCatalogクエリ(Query型フィールド)の定義
type Query {
"""カタログの書籍の一覧取得"""
booksInCatalog(
"""書名 (部分一致)"""
title: String
"""著者 (部分一致)"""
author: String
"""出版社 (部分一致)"""
publisher: String
"""出版年月日 (始点)"""
publishedOnFrom: Date
"""出版年月日 (終点)"""
publishedOnTo: Date
): [Book!]!
}
31
[GraphQL] 更新系操作の定義例
addBookToCatalogミューテーション(Mutation型
フィールド)の定義
type Mutation {
"""カタログへの書籍の追加"""
addBookToCatalog(
"""追加内容"""
input: AddBookToCatalogInput!
): AddBookToCatalogPayload
}
32
addBookToCatalogミューテーション用の入出力の
型定義
入力の型はinput 、出力の型はtype で定義す
る
input AddBookToCatalogInput {
"""書名"""
title: String!
"""著者"""
author: String!
"""出版社"""
publisher: String!
"""出版年月日"""
# ...(以下略)...
}
type AddBookToCatalogPayload {
"""追加された書籍"""
book: Book!
}
33
[gRPC] データモデル(エンティティ)の定義例
Bookデータのメッセージ型定義
= の右辺のフィールド番号でフィールドが識別さ
れる(ユニークに保ち、再利用しない)
// 書籍
message Book {
// 書籍ID
int32 id = 1;
// 書名
string title = 2;
// 著者
string author = 3;
// 出版社
string publisher = 4;
// 出版年月日
/* ...(中略)... */
// レビューの集計結果
ReviewSummary review_summary = 9;
}
34
ReviewSummary, Reviewデータのメッセージ型定
義
optional は省略可能フィールド
repeated は0個以上の繰り返しフィールド
// レビューの集計結果
message ReviewSummary {
// 平均ランク
optional float average_rank = 1;
// リスト
repeated Review reviews = 2;
}
// レビュー
message Review {
// ランク (星の数1?5)
optional int32 rank = 1;
// コメント
optional string comment = 2;
}
35
[gRPC] 参照系操作の定義例
BiblogApiサービスのListBooksInCatalogメソッド
の定義
// 書籍管理サービス"Biblog"のgRPC API
service BiblogApi {
// 書籍を一覧取得する
rpc ListBooksInCatalog(ListBooksInCatalogRequest) returns (
ListBooksInCatalogResponse);
}
36
ListBooksInCatalogメソッド用の入出力の型定義
message ListBooksInCatalogRequest {
// 書名 (部分一致)
optional string title = 1;
// 著者 (部分一致)
optional string author = 2;
// 出版社 (部分一致)
optional string publisher = 3;
// 出版年月日 (始点)
/* ...(以下略)... */
}
message ListBooksInCatalogResponse {
// 書籍のリスト
repeated Book books = 1;
}
37
[gRPC] 更新系操作の定義例
BiblogApiサービスのAddBookToCatalogメソッド
の定義
// 書籍管理サービス"Biblog"のgRPC API
service BiblogApi {
// 書籍を追加する
rpc AddBookToCatalog(AddBookToCatalogRequest) returns (AddB
ookToCatalogResponse);
}
38
AddBookToCatalogメソッド用の入出力の型定義
message AddBookToCatalogRequest {
// 書名
string title = 1;
// 著者
string author = 2;
// 出版社
string publisher = 3;
// 出版年月日
/* ...(以下略)... */
}
message AddBookToCatalogResponse {
// 追加された書籍
Book book = 1;
}
39
XaaS時代のWebサービスのインターフェース(API)
REST以外の方式も選択肢として検討しよう
スキーマ駆動開発を実践しよう
内部実装だけでなく設計について学ぼう
40
Further Reading
公式ドキュメント
OpenAPI Initiative
Getting Started | OpenAPI Documentation
GraphQL | A query language for your API
Introduction to GraphQL | GraphQL
gRPC
Introduction to gRPC | gRPC
Overview | Protocol Buffers Documentation
41
(REST) APIとその設計
『Web APIの設計』
『Web API: The Good Parts』
『Webを支える技術―― HTTP,URI,HTML,そ
してREST』
『APIデザイン?パターン』
42
GraphQL, gRPC
『初めてのGraphQL ――Webサービスを作って学
ぶ新世代API』
GraphQL in Action
How to GraphQL - The Fullstack Tutorial for
GraphQL
gRPC: Up and Running
API 設計: gRPC、OpenAPI、REST の概要と、それ
らを使用するタイミングを理解する| Google
Cloud 公式ブログ
43
サンプルコード
: REST API (Clojure)
cf.
: GraphQL API (Clojure)
cf.
: gRPC API (Clojure)
cf.
lagenorhynque/web-api-style-comparison
lagenorhynque/clj-rest-api
『3つのLisp 3つの世界』(電子版)
lagenorhynque/aqoursql
ClojureのLaciniaでGraphQL API開発してみた
lagenorhynque/route-guide
ClojureのProtojureでgRPC API開発してみた
44

More Related Content

インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC