---
# System prepended metadata

title: 2020-10-27 設計ナイト2020 @qsona's talk memo

---

# 2020-10-27 設計ナイト2020 @qsona's talk memo

GraphQL を利用したアプリケーションの設計パターン

## whoami

- @qsona [twitter](https://twitter.com/qsona)
- Software Engineer at Quipper Ltd
- Microservices, Rails, Node.js, GraphQL, [Prisma](https://www.prisma.io/)
- 近況: 新規サービス開発
  - [純粋培養GraphQL / Pure GraphQL Architecture - Speaker Deck](https://speakerdeck.com/qsona/pure-graphql-architecture)

## GraphQL

- [GraphQL | A query language for your API](https://graphql.org/)
- [「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ - エンジニアHub｜若手Webエンジニアのキャリアを考える！](https://eh-career.com/engineerhub/entry/2018/12/26/103000)
- [The NEXT of REST - onk.ninja](https://blog.onk.ninja/2017/09/21/the_next_of_rest)

設計的に重要なポイント: クライアントがクエリを宣言する = クライアントが自分で取得するデータを定義している

## クライアントサイドの設計

- REST API を叩くときと全く同じように設計することもできる
- たとえば Repository 層を設けている場合、そこが腐敗防止層になっているので、GraphQL API なのか REST API なのかはそこより内側では関係なくなる
- が、Repository 層を省略する方が良いこともある

Repository 層をつくらない理由

- デメリットがある
  - そもそもクライアントの Read Repository 層は作りにくい
    - [ざっくりCQRS/Event Sourcingを解説する - Speaker Deck](https://speakerdeck.com/j5ik2o/event-sourcingwojie-shuo-suru?slide=4)
  - Query はクライアントにとってのユースケースを表し、それにより over-fetching を防いでいるが、Repository 層を作るとそのメリットがなくなる
- メリットが少ない
  - そのまま使っても、腐敗しにくい
    - GraphQL Schema が明確なだけでなく、クライアントが自ら Query を定義している
  - そもそもクライアントにあまりドメインロジック置きたくない問題

### Apollo Stack (仮称)

特に Apollo Stack というものが存在するわけではないが、Apollo が提供するライブラリや考え方のうち、特に GraphQL 特有で設計に影響するものをピックアップした

- colocation
- Local-only fields

#### colocation

View Component と GraphQL の Fragment (queryの切れ端) をセットで持ちましょう、という考え方。親 Component がquery全体を組み立てる (文字列連結)。

- [Fragments - Client (React) - Apollo GraphQL Docs](https://www.apollographql.com/docs/react/data/fragments/#colocating-fragments)
- [GraphQLのFragment colocationとvariablesでモヤついている - Qiita](https://qiita.com/Quramy/items/1f9431b42d95ebdc59a8)

メリット: 各コンポーネントが必要とする部分をクエリとして宣言的に記述できる。

#### Local-only fields

(旧: apollo-link-state)

サーバーが提供する GraphQL Schema を拡張し、クライアント内で完結するフィールド・その取得/更新ロジックを追加する。

- [Local-only fields - Client (React) - Apollo GraphQL Docs](https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/)
- [apollo-link-stateで状態管理を行う - 技術探し](https://blog.hiroppy.me/entry/apollo-link-state)

## サーバーサイドの設計

REST API との比較

- 正直そこまで変わらない
  - グラフ構造、と言っても、トップレベルの Query Type / Mutation Type には REST のエンドポイントと同等のものが並ぶ
  - GraphQL Type Resolver 実装は、基本的に Model の JSON Serializer であり、似たようなものは REST でも存在することが多い
- Read系は、なるべくどんなクエリに対しても効率的に(N+1を発生させない)データ取得するようにしようとすると、少しむずかしくなる
- Write系は何も変わらない (= 難しいドメインなら普通に難しい)
- => CQRS的な発想がマッチするのでは

### Hasura

GraphQL のサーバー実装として興味深い事例に、Hasura がある

[Hasura | Instant GraphQL APIs for your data | Join data across databases, GraphQL & REST services to build powerful modern applications](https://hasura.io/)

一言で言うと、PostgreSQL(など)のテーブル定義をするだけで GraphQL API が使える

ダイニーさんの事例: [【エンジニアブログ】ダイニーのエンジニアリング3カ条｜dinii（ダイニー）公式｜note](https://note.com/dinii/n/n9be778bd7da3#qmpMF)

### Service to Service GraphQL

[GraphQL for service-to-service communication protocol - Speaker Deck](https://speakerdeck.com/qsona/graphql-for-service-to-service-communication-protocol)

## ここで一句

"Clean Arch もとの濁りの田沼恋しき"

## 座談会で話してみたいこと

- 初期の実装スピードを重視した技術スタック (Hasura, Firestore, Rails も入るかも, ...) が、大規模なシステムに育っていくときの登り方について
- 現実世界に即したアーキテクチャの導入方法。抽象化すべき/しないべき, レイヤーを設けるべき/設けないべきポイント