Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Breaking up the Monolith: Layered GraphQL Architectures

Breaking up the Monolith: Layered GraphQL Architectures

Johannes Schickling

June 15, 2018

More Decks by Johannes Schickling

Other Decks in Programming


  1. GraphQL is more than a REST wrapper GraphQL is great

    for… • Client-server communication • Service-to-service communication • Domain-driven design • Data modeling • Code generation • …
  2. Architectures are about tradeoffs • The one best architecture doesn’t

    exist • Architecture means always moving around tradeoffs • Scale • Performance • Development velocity • Cost • …
  3. Talk Overview Traditional Monolith Layers & Services: Breaking up the

    Monolith Service-to-service communication Architecture Case Studies 1 2 3 4
  4. What won’t be covered FOCUS OF THIS TALK TALK DOESN’T

    COVER • “Write path” (data processing/pipelines) • Infrastructure / Network • Deployment / CI/CD • “Read path” & state abstractions
  5. Traditional Monolith • Popular frameworks: Ruby on Rails, Laravel, Django,

    Meteor • DHH calls it the “Majestic Monolith”
  6. GraphQL Monolith Architecture • 3 tier architecture • Trend: Frontend

    and backend separated • Backend deployed as one package Frontend Backend Database
  7. Benefits of a Monolith Easy to get started, develop &

    debug No problems of distributed computing Simple infrastructure setup & easy deployment Global type-safety (when using typed language)
  8. Problems of a Monolith Developing a monolith becomes harder and

    harder over time Big/Growing monoliths can lead to the following problems: • Development velocity (hard to change, merge conflicts, …) • Operational complexity (scaling, bottleneck, …) • Code complexity (separation of concerns, …)
  9. Layers & Services • Goal: Break up complexity into smaller

    parts • 2 possible dimensions: • Vertically: (Abstraction) Layers • Horizontally: Services • Layers/services either logical or infrastructure • Some layers can be auto-generated
  10. Complexity Analysis Typical areas of code complexity • Blurry boundaries

    & coupling between logical domains • No separation of concerns • State handling } Introduce abstraction layers } Split up into services
  11. Challenges 1. Service-to-service communication 2. Preserve type-safety across services/layers 3.

    Requires changes to infrastructure setup & deployment workflow
  12. Service-to-service communication • How to communicate between services / layers

    • Request-response (sync) or message passing (async) • Considerations: • Cross language/platform compatibility • Efficiency (low network & serialization overhead) • Great workflow • Code generation
  13. How it works • Each service exposes a schema based

    on which service clients will be generated • Components: • Wire protocol (HTTP, gRPC) • Serialization format, IDL & type system (Protobuf, Thrift, Msgpack, …) • Framework & tooling (e.g. codegen) • Options: • RPC frameworks: gRPC, Thrift, … • Manual: REST / JSON over HTTP Service A Service B Generated Client for Service A Server for Service A (exposes schema) Serialized Data
  14. Code Generation Workflow 1. Define schema in IDL 2. Choose

    programming language(s) 3. CLI scaffolds server code and generates client libraries Example: Generates gRPC client in Go based on Protobuf schema protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
  15. GraphQL • Service-to-service communication using GraphQL • A Binding is

    (generated) schema-specific GraphQL client • Bonus: Supports schema delegation (~schema stitching) const serviceA = new ServiceA('http://service-a.example.com') const users = await serviceA.users({ activated: true }) const commentsWithAuthor = await serviceA.request(`{ comments { text author { name } } }`)
  16. Comparison: GraphQL vs gRPC gRPC: Low-level & performant • Server:

    Single handler function Very efficient / performant Supports streaming Static API (no queries) Requires explicit field ordering GraphQL: Flexible & powerful • Server: resolvers functions Flexible queries Supports schema delegation Bigger ecosystem Still early outside of JS/Node
  17. End-to-end type-safety • Global type-safety for decoupled & distributed systems

    • GraphQL acts as glue between all layers & services • Especially powerful in CI/CD setups
  18. Stateless Monolith • Similar to monolith but all state is

    moved into data services • Stateful: in-mem state across reqs Pros: Can be run serverless Cons: Still code complexity issues
  19. Microservice Architecture • Thin GraphQL gateway layer • Often auto-generated

    based on schema merging • Microservices contain business logic + each MS has its own database Pros: Rigid boundaries & scalable Cons: Infrastructure overhead
  20. Layered Service Architecture • Based on Microservice Architecture • GraphQL

    gateway layer is optional • Presentation services give frontend engineers more flexibility/control • Pros/Cons: Same as MS architecture
  21. Key Takeaways GraphQL is a great foundation for any architecture

    GraphQL shines at service-to- service communication A “Stateless Monolith” is a great starting point for new backends 1 2 3
  22. • DB-agnostic Data Access Layer (think ORM) • Prisma turns

    your DB into a GraphQL API • Your API server delegates queries to Prisma Prisma