SlideShare a Scribd company logo
1 of 44
Download to read offline
インターフェース定義言語から学ぶ
モダンな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

More from Kent Ohashi

Team Geek Revisited
Team Geek RevisitedTeam Geek Revisited
Team Geek RevisitedKent Ohashi
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesScala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesKent Ohashi
 
Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Kent Ohashi
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)Kent Ohashi
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングKent Ohashi
 
実用のための語源学入門
実用のための語源学入門実用のための語源学入門
実用のための語源学入門Kent Ohashi
 
メタプログラミング入門
メタプログラミング入門メタプログラミング入門
メタプログラミング入門Kent Ohashi
 
労働法の世界
労働法の世界労働法の世界
労働法の世界Kent Ohashi
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSLKent Ohashi
 
RDBでのツリー表現入門
RDBでのツリー表現入門RDBでのツリー表現入門
RDBでのツリー表現入門Kent Ohashi
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
たのしい多言語学習
たのしい多言語学習たのしい多言語学習
たのしい多言語学習Kent Ohashi
 
Ductモジュール入門
Ductモジュール入門Ductモジュール入門
Ductモジュール入門Kent Ohashi
 
Clojure REPL: The Good Parts
Clojure REPL: The Good PartsClojure REPL: The Good Parts
Clojure REPL: The Good PartsKent Ohashi
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made EasyKent Ohashi
 
Clojurian Conquest
Clojurian ConquestClojurian Conquest
Clojurian ConquestKent Ohashi
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
GraphQL API in Clojure
GraphQL API in ClojureGraphQL API in Clojure
GraphQL API in ClojureKent Ohashi
 

More from Kent Ohashi (20)

Team Geek Revisited
Team Geek RevisitedTeam Geek Revisited
Team Geek Revisited
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesScala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
 
Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
 
実用のための語源学入門
実用のための語源学入門実用のための語源学入門
実用のための語源学入門
 
メタプログラミング入門
メタプログラミング入門メタプログラミング入門
メタプログラミング入門
 
労働法の世界
労働法の世界労働法の世界
労働法の世界
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSL
 
RDBでのツリー表現入門
RDBでのツリー表現入門RDBでのツリー表現入門
RDBでのツリー表現入門
 
GraphQL入門
GraphQL入門GraphQL入門
GraphQL入門
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
たのしい多言語学習
たのしい多言語学習たのしい多言語学習
たのしい多言語学習
 
Ductモジュール入門
Ductモジュール入門Ductモジュール入門
Ductモジュール入門
 
Clojure REPL: The Good Parts
Clojure REPL: The Good PartsClojure REPL: The Good Parts
Clojure REPL: The Good Parts
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy
 
Clojurian Conquest
Clojurian ConquestClojurian Conquest
Clojurian Conquest
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
GraphQL API in Clojure
GraphQL API in ClojureGraphQL API in Clojure
GraphQL API in Clojure
 
法学入門
法学入門法学入門
法学入門
 

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