kenju's blog

About Programming and Mathematics

Reading Notes of "The Road to GraphQL": "What is GraphQL?" Section

Where can I get the book?

What is GraphQL?

  • an open source query language created by Facebook
  • Facebook used it internally for their mobile applications since 2012, as an alternative to the common REST architecture
  • allows requests for specific data, giving clients more control over what information is sent
  • is not opinionated about the network layer, which is often HTTP, nor about the payload format, which is usually JSON
  • is not opinionated about the application architecture

It is only a query language

GraphQL Advantages

  • declarative data fetching
  • no over-fetching with GraphQL
  • general solution over multiple frameworks (React, Angular, Node, etc.)
  • single source of truth
  • schema can be easily stitched
  • strongly typed
  • versionless (no API versions)

GraphQL Disadvantages

  • query is complex
  • rate limiting handling is complex
  • caching is more complex than REST

People often mistake GraphQL as a replacement for server-side databases, but it's just a query language

Reading Notes of "Designing Data-Intensive Applications" Chapter 12: The Future of Data Systems

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

に続き、Chapter 12 の Reading Notes. ついに最終章。

Reading Notes


  • Data Integration
    • Combining Specialized Tools by Deriving Data
      • Reasoning about dataflows
      • Derived data versus distributed transactions
      • The limits of total ordering
      • Ordering events to capture causality
    • Batch and Stream Processing
      • Maintaining derived state
      • Reprocessing data for application evolution
      • The lambda architecture
      • Unifying batch and stream processing
  • Unbundling Databases
    • Composing Data Storage Technologies
      • Creating an index
      • The meta-database of everything
      • Making unbundling work
      • Unbundled versus integrated systems
      • What's missing?
    • Designing Applications Around Dataflow
      • Application code as a derivation function
      • Separation of application code and state
      • Dataflow: Interplay between state changes and application code
      • Stream processors and services
    • Observing Derived State
      • Materialized views anc caching
      • Stateful, offline-capable clients
      • Pushing state changes to clients
      • End-to-end event streams
      • Reads are events too
      • Multi-partition data processing
  • Aiming for Correctness
    • The End-to-End Argument for Databases
      • Exactly-once execution of an operation
      • Duplicate supression
      • Operation identifiers
      • The end-to-end argument
      • Applying end-to-end thinking in data systems
    • Enforcing Constraints
      • Uniqueness constraints require consensus
      • Uniqueness in log-based messaging
      • Multi-partition request processing
    • Timeliness and Integrity
      • Correctness of dataflow systems
      • Loosely interpreted constraints
      • Coordination-avoiding data systems
    • Trust, but Verify
      • Maintaining integrity in the face of software bugs
      • Don't just blindly trust what they promise
      • A culture of verification
      • Designing for auditability
      • The end-to-end argument again
      • Tools for auditable data systems
  • Doing the Right Thing
    • Predictive Analytics
      • Bias and discrimination
      • Responsibility and accountability
      • Feedback loops
    • Privacy and Tracking
      • Surveillance
      • Consent and freedom of choice
      • Privacy and use of data
      • Data as assets and power
      • Remembering the Industrial Revolution
      • Legislation and self-regulation
  • Summary


  • derived data
    • A dataset that is created from some other data through a repeatable process, which you could run again if necessary
  • unbundling databases
  • the lambda architecture
  • Elm, React, Flux, Redux
  • materialized views
    • to perform a computation eagerly and write out its result, as opposed to calculating it on demand when requested
  • tracking


  • How to solve data integration problem? ... using batch processing and event streams to let data changes flow between different systems
  • The author suggests: *unbundling the components of a database, and building an application by composing these loosely coupled components
    • e.g. Unix pipe shell-like dataflow description like mysql | elasticsearch

AWS Dev Day Tokyo 2018 Day 3 に参加してきました

現在広告チームでの Microservices 化に取り組んでいるため、他社の事例や導入時の工夫や苦労を学びたかったので、Day 3 だけ参加してきた。 現在の業務でまさに悩んでいる・取り組んでいる課題について、他の人が自分の知らなかった知識や技術で解決している例を見るのは、設計の引き出しを増やすために大切だということを再認識。

  • 得た知識
    • Event Sourcint / CQRS という設計パターン
    • Event Driven なデータフローにすることでレガシーアプリケーションを徐々にリファクタしていくという考え方
    • Access token propagation / Client credentials grant という概念
    • Micro frontends という概念と、その実装パターン
    • FiNC 社における、実際の Micro frontends の実装パターン
    • Web Components (Custom Elements) API






Micro-services の定義から、導入する際に Step-by-Step で進めていこうという一般的な話。

  • Step1 : 最初のサービスを分割する
  • Step2 : サービス基盤を整備する
  • Step3 : サービスを管理する

それぞれの Step での具体的な実装パターンやプラクティスに関しての深掘りはなかった。 しかし、各 Step へ進むかどうかの判断ポイントが参考になった。


  • Step1 : サービスの分割点はビジネス視点で決定すること
  • Step2 : 分割と集約のバランスを考える(<=> サービス間を疎結合にできないなら分割すべきではない)
  • Step3 : オーバーキル問題(導入が早すぎると管理コストばかりがかかる)

Event Sourcing+CQRSを活用するスケーラブルアプリケーション開発



複雑化するアプリケーション間の連携を考えるときに、Event Driven で考えようという話。 API を設計するときのベースに、Event Sourging / CQRS を取り入れることを推奨。

複雑なライフサイクル、ステート管理を内包したレガシーアプリケーションをリファクタリングする引き出しの一つとして、 Event Driven で責務を分離していく、というメタな議論が聞けたのが良かった。

Event Sourcing / CQRS が登場したのは 2010 年代前半くらいからようなので、アイデアとしてはある程度良い意味で枯れているのかもしれない。そこに、Apache Kafka の国内外での知見が増えてきたり、Cloud Pub/Sub (GCP) や Kinesis (AWS) などの Managed な Message Broker が出てきて、導入事例も増えてきているのかもしれない。

でも、個人的には 典型的な N-tier から Event Driven にがっと置き換えるのってかなり体力使うのでは、という印象(やったことないので、やったことある方いたらぜひ聞いてみたいです)。 の記事が、典型的な N-tier app から CQRS/Event Sourcing をベースとしたアプリへの進化がさくっとわかる良い記事だと感じた。


Discussion Points

  • どう実装するか
  • Scalability は担保できるか?(全てのイベントを保存するとコストが高い)
  • 巻き戻しの処理はどうするか

CQRS Patterns

  • Command (Write) / Query (Read) を分離することで、データの流れを一方通行にする
    • Command = with side effect
    • Query = no side effect
  • Consistency / Scalability / Performance など、Read/Write で求められる要件は異なる
    • 分離することで、インフラレベルでの柔軟性もあがる




予約時にすでに埋まっていたので泣く泣く別のセッションを申し込んでいたのですが、なんとか当日受付で入れたので受講してきた。 Micro services 化したときに必ずと行っていいほど共通化するのが認証・認可の話。

AWS Managed Console みたいな、サブドメイン切って別々の認証・認可の状態を Auth 専用サービスで管理しながら、別々のサービスを提供するようなサービス("Microfrontends w/ Auth")を作る場合の知見が詰まっていた。


  • Authentication or Authorization
  • Basic Auth
  • Request Auth
  • Digest Auth
  • OAuth 2.0
  • Access token propagation
  • Client credentials grant
  • OpenID Connect 1.0
  • Microfrontends

401 / 403 Error

  • 401 Unauthorized -> 認証の失敗 = "お前誰だよ"
  • 403 Forbidden -> 認可の不足 = "理解した。だが断る"

Access token propagation / Client credentials grant

  • Access token propagation
    • 権限委譲を用いた認証
    • access token を intermediate servers が横流しする感じ
  • Client credentials grant
    • クライアント単位のアクセス認証
    • intermediate servers それぞれ独自のアクセスとして認証

あくまで、ユーザー(消費者)がデータの持ち主である、という思想である prismatix では、Access token propagation 戦略を採用している。 


The idea behind Micro Frontends is to think about a website or web app as a composition of features which are owned by independent teams. Each team has a distinct area of business or mission it cares about and specialises in. A team is cross functional and develops its features end-to-end, from database to user interface.

AWS Managed Console は、裏側で細かい認証・認可の管理をしながら、各サービスの管理画面を提供している、Microfrontends w/ Auth の典型的な例とのこと。サブドメイン切って SSO する。そのためには、各アプリの認証の状態を横断的に管理する Auth 専用サービスが必要。

BFF introduction



BFF Patterns

  • API Aggregation (there are so many microservices behind the BFF)
  • Session Management
  • Server-side rendering
  • File upload
  • Web Socker / Long Polling / SSE


When BFF, When NOT BFF

When BFF

  • improve enhancement speed per frontend/backend programmers
  • some use cases requirements (e.g. SSR due to SEO, Realtime w/ Web Socket)
  • wrapper for legacy architecture


  • many full stacks (who can develop both frontend/backend)
  • priority (market-in speed is required in monolithic architecture)
  • no use cases requirementsa (e.g. SSR due to SEO, Realtime w/ Web Socket)

BFF Anti-Patterns

Micro Frontends の理論と実践



  • Frontend Monolith
  • Micro Frontends
  • Web Components
    • Custom Elements


発表を聞いたわけではないのだが、Micro Frontends について詳細な資料。

  • いかに Micro Frontends を実装するか
  • 実際に導入してみてどうだったか


広告業界とかも、もっと iframe がんがんつかう時代からは早く脱却して、Component base で提供できるような広告枠のやり取りができるようになるといいんだろうなー。cookpad 本体と広告チーム管理の DOM Element の分離もしかり。

FiNC のこの事例の背景については、以下のブログ記事も参考になった。

Building and Running Microservices with AWS


"Microservices on AWS"


Amazon warehouse における Inbound/Outbound チーム間で、共通の"在庫テーブル"を密結合で使っていたがゆえの課題を、Microservices で解決した話。

Microservices 化するにあたって、在庫管理のビジネスプロセス自体から見直していったとのこと。これだけ Microservices 化が叫ばれている中で、技術先行ではなくあくまでビジネス要件や組織体系を反映した分割をするべき、という具体例の一つ。

Amazon 社内でも Monolithic なサービスが存在していたのだが、ALB のパスペース/ホストベースのルーティングを活用して Amazon 自体でも Microservices 化を推進していったという背景についても触れられていた。ココらへんが、自社の課題を解決するためのツールとして AWS が進化してきたということなのだろうか。

My Understanding about GraphQL vs REST



  • Client side の実装は圧倒的に楽になる
    • 複数 endpoints からリソースをとってきてまとめる処理が不要になる
    • Versionless で開発できる
  • Server side の労力は変わらない
    • REST 同様開発する必要がある
    • むしろ、REST での Best Practices や定石が効かない(N+1 や Batching 対応など)
  • Ecosystem や Best Practices は整ってきた印象
    • 海外でも国内でも採用事例を聞くようになってきた
    • Monitoring はまだまだ磨き込みの余地あり
      • 例えば、AWS AppSync の Managed Console では 2018 年 11 月初頭現在ほぼなにも監視項目がない(他の AWS Lambda / AWS DynamoDB と比べて貧弱)


[Client] Fetch associated data with multiple HTTP requests

Client side では、欲しいデータが Nest されていたり関連があったりする場合でも、1 HTTP Request でリクエストすることができる。これによって、本来複数リクエストを必要としていたリソースの取得も、1 turn around で実現できる。

ただし、これは Client side から見た場合の話であって、Server side ではそれに対応した実装を行う必要がある。

[Client] Clients cannot tell which data to retrieve

よく言われるように、Client side で必要な attributes を指定できる。これによって、Client side が何を必要としているかが、宣言的に記述できる。

例えば、/repositories/ でレポジトリ情報を取得しようとする。

query { 
  repository(owner: "kenju", name: "2djs") {
    primaryLanguage {

GraphQL になる前の Facebook graph API では、Client side が返して field を Request 側で指定できるものの、殆どの場合はそうではない。

REST の場合、Repository.nameとRepository.primaryLanguage` だけが欲しい場合でも、往々にして不要な attributes も一緒に返ってきてしまう。ネットワーク帯域を無駄遣いしてしまっている。


[Client/Server] Everything is typed

GraphQL では、型宣言が必須である。

後述する通り、 REST でも型は定義できる。しかし、言語仕様自体に組み込まれているか否か、というのはかなり大きな差だと考える。

[Client/Server] Documentation is a first citizen

Schema があるということは、自動生成ドキュメントや mock server もつくりやすくなる。

とはいえ、REST でもこの手のツールはかなり開発されていて使いやすいツールも多いので、REST と比べて優れている、というわけではない。

[Server] Think in Graphs

Graphs are powerful tools for modeling many real-world phenomena because they resemble our natural mental models and verbal descriptions of the underlying process. With GraphQL, you model your business domain as a graph by defining a schema;

結局の所、Graph ベースで考えるのに向いた Application(e.g. SNS)にはビジネスロジックとデータの宣言が非常に seamless につながって考えられるようになる。Application によっては、REST を導入することによって Graph modeling を Client side で解体して CRUD base で考える、ということをしなくてよくなるので、開発者体験はかなりあがるはず。

また、Graph modeling が一見適していないような従来の管理アプリケーションや普通の CRUD Application でも、「Grpah で考えてみたらどうなるんだろう」という、ビジネスロジックを改めて見つめ直すきっかけをもたらしてくれる。

逆に言うと、Graph ベースで考える必要がある、ということ。例えば、Pagination について、Relay Cursor Connections Specification という仕様が公開されているけれど、offset/limit base で考える Pagination ではなく、cursor base (nodes/edges) で考える必要がある。これは、Feed や Timeline のような Application には向いているが、ページ数ベースで考える kaminari を使っているような Application には向いていない。

REST/GraphQL both does...

Can be typed

REST でも、JSON Schema を使えば型はつけられる。ポイントは、それが任意であり、API 開発者の判断に委ねられているということだ。

GraphQL では、型の宣言自体が仕様に組み込まれている。これによって、必ず型を宣言する必要が生まれてくることで、一定の制約が生まれる。

一般的には、複数クライアントの複数バージョンからリクエストされることを考えると、型という一定の制約があったほうが、Client side での Response Data のハンドリングは自明になる。逆に言うと、JSON Schema が無い field で文字列が返ってくるのか数値が返ってくるのかが自明的ではない場合、Client side で型判定したり Casting したりする必要が出てくる。 

GraphQL Resources - "Lessons from 4 Years of GraphQL"

"GraphQL First Impression" にも書いたけれど、GraphQL を導入して、フロントエンドのビジネスロジックを中心にリアーキテクチャリングを進めている。 GraphQL 周りで見たいくつかの Resources の読書メモについて、まとめておく。


"Lessons from 4 Years of GraphQL"

GraphQL の作者のひとりでもある、元 Facebook の Lee Byron による "Lessons from 4 Years of GraphQL" の視聴メモ。 GraphQL に限らない Practices も多いけれど、"Think in Graphs, not Endpoints" や "GraphQL is a thin layer" あたりは、設計の骨子として覚えておいて損はない。

  • Naming matters
    • Question: "What might version 2 look like?"
  • Think in Graphs, not Endpoints
  • Describe the data, not the view
    • Question: "Will this work for all future clients?""
  • GraphQL is a thin layer
  • Hide implementation details
    • Question: "What if the implementation changes?"
  • Solve a Real Problem
  • Think like the client
  • Have a First Client
  • Incremental Adoption
  • Avoid "Second System Syndrome""
  • Timing is critical (Recognize Inflection Points)
  • Encourage taking measured risks

Reading Notes of "Discretized Streams: An Efficient and Fault-Tolerant Model for Stream Processing on Large Clusters"

The paper about D-Streams (discretized streams), a.k.a micro batching, which is prototyped in Spark Streaming.

Matei Zaharia, Tathagata Das, Haoyuan Li, et al.: "Discretized Streams: An Efficient and Fault-Tolerant Model for Stream Processing on Large Clusters," at 4th USENIX Conference in Hot Topics in Cloud Computing (HotCloud), June 2012.

Reading Notes

D-Streams Concept

  • D-Streams is prototyped in an extension to the Spark cluster computing framework called Spark Streaming
  • record-at-a-time processing model has a limitation for Fault tolerance, Consistency and Unification with batch processing
  • The key idea behind D-Streams is to treat a streaming computation as a series of deterministic batch computation on small time intervals
  • RDDs (resilient distributed datasets) .... an efficient storage abstraction that avoids replication by using lineage for fault recovery


D-Stream Operators

Two types of operators for building streaming programs:

  • Transformation
    • produce a new D-Stream from one or more parent streams
    • stateless or stateful
  • Output
    • let the program write data to external system

Stateful operators that work over multiple intervals:

  • Windowing
    • groups all of the records from a range of past time intervals into a single RDD
  • Incremental aggregation
    • count or sum
  • Time-skewed joins
    • join a stream agains its own RDDs from some time in the past to compute trends

parallel recovery

parallel recovery is how D-Streams guarantee fault tolerance.

  • the system periodically checkpoints some of the state RDDS, by asynchronously replicating them to other nodes
  • when a node fails, the system detects the missing RDD partitions and launches tasks to recover them from latest checkpoint


Spark revolves around the concept of a resilient distributed dataset (RDD), which is a fault-tolerant collection of elements that can be operated on in parallel. There are two ways to create RDDs: parallelizing an existing collection in your driver program, or referencing a dataset in an external storage system, such as a shared filesystem, HDFS, HBase, or any data source offering a Hadoop InputFormat.

And here is the paper about the RDD's core concept:

Related Works

Reading Notes of "Designing Data-Intensive Applications" Chapter 11: Stream Processing

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

に続き、Chapter 11 の Reading Notes.

Streaming Processing については、過去にガッツリリアルタイムログ基盤を作ったことがあり、その際にこの Chapter に書いてあるようなことを調べた記憶があります。そのときに本書を読んでおきたかった・・・

"cookpad storeTV の広告配信を支えるリアルタイムログ集計基盤" や以下スライドをご覧ください。


  • Transmitting Event Streams
    • Messaging Systems
      • Direct messaging from producers to consumers
      • Message brokers
      • Message brokers compared to databases
      • Multiple consumers
      • Acknowledgments and redelivery
    • Partitioned Logs
      • Using logs for message storage
      • Logs compared to traditional messaging
      • Consumer offsets
      • Disk space usage
      • When consumers cannot keep up with producers
      • Replaying old messages
  • Databases and Streams
    • Keeping Systems in Sync
    • Change Data Capture
      • Implementing change data capture
      • Initial snapshot
      • Log compaction
      • API support for change streams
    • Event Sourcing
      • Deriving current state from the event log
      • Commands and events
    • State, Streams, and Immutability
      • Advantages of immutable events
      • Deriving several views from the same event log
      • Concurrency control
      • Limitations of immutability
  • Processing Streams
    • Uses of Stream Processing
      • Complex event processing
      • Stream analytics
      • Maintaining materialized views
      • Search on streams
      • Message passing and RPC
    • Reasoning About Time
      • Event time versus processing time
      • Knowing when you're ready
      • Whose clock are you using, anyway?
    • Stream Joins
      • Stream-stream join (window join)
      • Stream-table join (stream enrichment)
      • Table-table join (materialized view maintenance)
      • Time-dependence of joins
    • Fault Tolerance
      • Microbatching and checkpointing
      • Atomic commit revisited
      • Idempotence
      • Rebuilding state after a failure
  • Summary




2 types of message brokers:

  • AMQP/JMS-style message broker
    • queueing oriented
    • messages will be removed from the broker once they have been acknowledged
  • Log-based message broker
    • guarantee messages orders
    • parallelism is achieved by partitioning
    • consumers track their progress by checkpointing the offset of the last message
    • broker retain messages on disk -> can replay events

3 types of joins:

  • Stream-stream joins
    • both input streams consist of activity events
    • the join operator searches for related events that occur within some window of time
  • Stream-table joins
    • one input stream consists of activity events, while the other is a database change-log
    • the change-log keeps a local copy of the database up to date
  • Table-table joins
    • both input streams are database changelogs

『The Hardware Hacker』を読んだ

ハードウェアハッカー ~新しいモノをつくる破壊と創造の冒険

ハードウェアハッカー ~新しいモノをつくる破壊と創造の冒険


Hardware 業界では有名な、Andrew Bunnie Huang による著作。

chumbychibitoronics などを手がけた起業家でもあり、ハッカーでもある著者のこれまでの起業の裏話や、深センにおけるプロダクトの作り方、苦労話から、彼の哲学が垣間見えてきて、飽くなき知的好奇心をとことんまで追求するあまり、話は遺伝工学とウィルスの DNA をハッキングするという話題まで言及している。

これだけ読んでいてわくわくさせられる本は久々に読んだ。下手に技術書を読むより、知的好奇心がこの上なく刺激される。彼の考え方や生き方に、新しい発想の仕方や視座を学んだ。 こんな本が書けるようなハッカー人生は、最高に楽しいと思う。


このまま今の会社にいていいのか?と一度でも思ったら読む 転職の思考法

このまま今の会社にいていいのか?と一度でも思ったら読む 転職の思考法


  • 転職を考えている人だけではなくて、今の会社での自分のキャリアラダーについて悩んでいる人におすすめ
  • というか、むしろ転職したいというときに読むのだと少し遅い気もする
  • 仕事でいかに成果を出すか、そしていかに市場価値を上げるかについて、考え直すきっかけになる


  • 転職をしようと思って手にとったわけではなく、"『転職の思考法』を読んでキャリア棚卸しシートを作りました" が Timeline に流れてきたから
    • 新卒で入った会社でお世話になった先輩のブログ
  • 自分のエンジニアとしての成長曲線と、仕事での成果、そして身につけるべき技術について、一度腰を据えて考え直すきっかけをちょうどほしいと思っていた頃合いでもあったから


  • これを読むだけでは自分の市場価値は上がらない。これを読んで、自身の仕事のスタイルや注力する働き方を内省するなど、実際にアクションに起こさないと「やった気になった」症候群で終わってしまう
    • 自分は本書を読んだあと、実際に Career Sheet を作り、得ている経験やスキル、今後の進みたい方向について長大な Google Document を書きました
  • 転職エージェントとの win-win な関係の築き方や、転職時に抑えておきたいポイントが分かる
    • 今回は流し読みした程度だけれども、転職するタイミングには、読み返したい
  • 「転職は悪」といった、日本の旧態依然とした固定概念に対して気持ちいいくらいに建設的な批判と改善策を提案している
    • エンジニア業界はそこまでそういう文化に蝕まれてはいないけれど
    • 謎の一括採用システムに疲弊してしまった後輩や、転職しようと悩んでいる友人に勧めようと思っている





GraphQL First Impression

最近 10 年超えの Rails App に GraphQL/React/Apollo を導入した。

legacy / beta の 2 世代の View が存在し、フロント側のコードも開発がかなりつらい状況だった。 広告配信を支える入稿アプリケーションで、裏側の配信とのつなぎこみ部分は、自分の前任者の方々がかなりリファクタリング・リアーキテクチャを頑張ってくれたので書きやすい部分も多いのだが、フロント側のコードとのつなぎこみや、2 世代存在する Models など、決して Developer Experience が高くない状況だった。


  • GrpahQL/React/Apollo を導入したり
  • JavaScript のテストも存在しなかった管理アプリケーションで、Snapshot Testing (Jest) を導入したり
  • ESLint のルールを拡充して ES6 の文法をデファクトスタンダードにしたり
  • CoffeeScript を全撤廃したり
  • jQuery 1.x の依存を可能な限り減らしていったり
  • デッドコードや未使用 CSS を地道に消していったり
  • Feature Spec を見直して、テストする意義がないと判断した Spec については削除したり
  • package.json のライブラリを定期的にアップデートしたり(そもそも未使用ライブラリも存在していた・・・)
  • GraphiQL/GraphQL Voyager/graphql-docs などの開発者機能を統合したり

などなど、かなりフロントエンド開発の Developer Experience が上がってきたと思う。

その一番の理由は、なんといっても GraphQL を BFF として導入したこと。サーバーサイドは相変わらず REST と同様実装する必要があるし、Best Practices が REST と違う分新たに考慮したりキャッチアップしたりしなくては行けない部分も増えたのだけれども、フロントエンドの開発が圧倒的にコスパよく開発・改修できるようになった。Versionless な API、ほしいデータを宣言的に定義する Declarative な開発スタイル、Schema 定義を強制されることで程よく制約がかけられた API など、REST にはない魅力がそこにはあった。

まだまだ磨き込みもしていく必要があって、例えばモニタリングや Batch Loader / Optimistic UI / Caching Strategy をどうしていくかは検討中。TypeScript の導入や State Management のブラッシュアップも次なる手段として検討している。

フロントエンドエンジニアがいないからこそ、コスパよく機能開発をでき、Legacy System をいい感じにカプセル化でき、徐々に進化するシステムを作っている感触があって、すごく楽しい。引き続き設計もシステムも磨き込んでいくので、またアップデートがあったらまとめようと思う。