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

Backends for frontends with GraphQL

Backends for frontends with GraphQL

This talk crosscuts frontend and backend development as we explore the way of how to build better API’s when your application has multiple different user interfaces. Imagine an application that has a web, mobile and watch UI. They all offer different functionality and therefore require access to different information and functions. A default solution in such a situation would be to try to build a generic backend that can be used by all clients. But trying to build a one size fits all solution often backfires and raises multiple questions, e.g.:

- Who owns the API and how to implement changes required by different UI teams?
- What interface to use?
- What if two clients need the same data in different shapes?
- How to optimize the APIs for different clients?
- What to do when the API gets too large?

Having a generic backend for all UI’s leads to mediocre performance, degraded user experience as well as additional communication overheads for the development teams. Seeing how this approach doesn’t work we can go in another direction: build different API services for different clients. Thus enter Sam Newman’s Backend For Frontend pattern that inroduces the idea of having a separate backend for each type of UI in your application. Add the newly popular GraphQL API on on top, and you now have the means to take this pattern to a whole new level. During this talk we will explore how using the BFF pattern and GraphQL can help us address the quetions we’ve listed before and improve our overall application architecture.

Avatar for Pavels Jelisejevs

Pavels Jelisejevs

June 14, 2018
Tweet

More Decks by Pavels Jelisejevs

Other Decks in Technology

Transcript

  1. WHO AM I? ➤ My name is Pavels Jelisejevs ➤

    I’m a software engineer in C.T.Co Riga ➤ I have a background in UI development ➤ Now I’m more interested in full stack development, cloud architecture and DevOps
  2. WHAT ARE WE GOING TO TALK ABOUT? ➤ The problems

    of maintaining an API that’s serving different clients (e.g. web, mobile etc) ➤ What is the Backend For Frontend pattern and how can it be useful ➤ What is GraphQL and how can we leverage it this context
  3. WHY AM I TALKING ABOUT THIS AT FRONTEND CONFERENCE? ➤

    I believe, that API design should be driven by the client, not the owners of the API ➤ When it comes to client-facing API’s, the frontend development team is the client ➤ Thus, the frontend team must be driving the API
  4. SETTING UP THE SCENE ➤ You are working on a

    young and growing website that sells vintage cars ➤ The website has a single page application desktop UI ➤ The UI communicates to an API that abstracts away the downstream services ➤ The API is tailored for the web client to avoid unnecessary traffic and requests ➤ So far so good Product service Order service Payment service RESTful/RPC API
  5. ENTER THE MOBILE UI ➤ Business is booming and you

    decide that you need to expand further by introducing a mobile app ➤ The UX of the mobile app is different from the desktop: it requires less data and has less features ➤ The API serves excessive traffic for the mobile client, so performance is inferior Product service Order service Payment service RESTful/RPC API
  6. POSSIBLE SOLUTIONS ➤ Create custom endpoints or methods per UI

    (/products/list-for- desktop and /products/list-for-mobile) ➤ Forces you to have a pre-defined list of endpoints ➤ Overall design of the API becomes blurry ➤ Use protocols like OData to get more control over the returned data ➤ Limited querying capabilities (e.g. filtering expanded elements) ➤ Complex query constructs ➤ Limited tooling support ➤ Use a custom protocol to pass the client’s context to the API ➤ A bad idea in general
  7. ENTER TWO MORE CLIENTS ➤ You decide to start accepting

    orders over the phone and via smart watches ➤ The API interface becomes complex and bloated with different client-specific endpoints ➤ Performance and UX suffers on all clients ➤ The backend team needs to keep up with the needs of each client Product service Order service Payment service Restful/RPC API
  8. TWO MAJOR PROBLEMS ARISE ➤ It’s technically difficult to satisfy

    the requirements of all clients via a single API ➤ The API team needs to handle requests coming from default UI teams
  9. WHAT IS A BACKEND FOR FRONTEND? ➤ A Backend For

    Frontend (BFF) is a transformation layer between your clients and your API ➤ It’s task is to aggregate data from the downstream services and present it in a way that is tailored for a particular user experience ➤ The BFF does not implement business or application logic, only data transformation and aggregation
  10. BACK TO THE MOBILE UI ➤ The desktop and mobile

    clients each get their own BFF ➤ The desktop BFF might expose full product information with rich text and image data ➤ The mobile BFF might return a leaner product list with additional information being served separately and on- demand Product service Order service Payment service Restful/RPC API Mobile BFF Desktop BFF
  11. WHO OWNS THE BFFS? ➤ Since the BFF serves the

    need of a particular client, it makes sense for it to be owned by the team maintaining that client ➤ This will allow them to implement features independently from the API team and speed up their development process ➤ The team is free to choose the tech stack for their BFF ➤ The API team can then focus on exposing a domain-oriented interface and implement business features on that level Product service Order service Payment service Restful/RPC API Mobile BFF Desktop BFF Web team Mobile team API team
  12. HOW MANY BFFS? ➤ Option 1: One BFF for each

    user experience (desktop vs mobile). Similar clients might share the same BFF (iPhone and Android clients) since their UX might be identical ➤ Option 2: One BFF per team. This will allow the teams to choose their own tech stack and work independently (applying Conway’s law)
  13. PROBLEMS AND PITFALLS ➤ Code duplication ➤ As with micro

    services, a certain share of code duplication is present - that’s acceptable ➤ If needed, duplicated code can be refactored into libraries or services, but this increases coupling ➤ Adding business logic into the BFF ➤ Business logic belongs in the downstream services (can be then reused by different BFFs) ➤ It might be acceptable to address cross-cutting concerns in the BFF, such as, authorization or logging ➤ Returning unnecessary information ➤ To minimize network traffic, the BFF must only return information that is required by the client
  14. “GraphQL is a query language for APIs and a runtime

    for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more …
  15. ASK FOR WHAT YOU NEED ➤ GraphQL allows the client

    to ask only for the data they need and provides a server runtime to easily resolve such queries and return the requested data ➤ This capability makes it an ideal candidate to be used as a communication protocol with the BFF as it puts the client in charge
  16. ASK FOR WHAT YOU NEED { allCars { make }

    } { "data": { "allCars": [ { "make": "Ford" }, { "make": "BMW" }, { "make": "Mercedes-Benz" } ] } } GET/POST Request Response
  17. ASK FOR WHAT YOU NEED { allCars { make model

    } } { "data": { "allCars": [ { "make": "Ford", "model": "Mustang" }, { "make": "BMW", "model": "2002" }, { "make": "Mercedes-Benz", "model": "SL" } ] } } Request Response GET/POST Request
  18. PASS PARAMETERS TO FIELDS { allCars(make: “BMW”) { make model

    } } { "data": { "allCars": [ { "make": "BMW", "model": "2002" } ] } } Request Response GET/POST Request
  19. HOW DOES IT WORK ➤ The GraphQL client sends the

    request to the GraphQL server ➤ The server parses and validates and the query against the schema ➤ Each field is mapped to a resolver, a function that is responsible for fetching the data ➤ The data can be fetched from a remote service, a database or other source BFF Product service Order service Payment service Product resolver Order resolver Payment resolver Client App GraphQL server GraphQL Client HTTP /graphql
  20. DEFINE A STRICT CONTRACT ➤ You can describe your API

    by using a strictly type schema ➤ Each field can be assign either a primitive type or a custom composite type ➤ Each query you make will be validated against the schema and an error will be triggered in case the types don’t match ➤ This schema is used by different tools to provide documentation and a playground for your application type Car { make: String! model: String! year: Int! id: ID! }
  21. REQUEST DATA FROM MULTIPLE SOURCES ➤ You can request data

    from fields that are resolved from different sources, for example, cars and orders with a single request ➤ This can help reduce the amount of network connections made to load the data ➤ You can group or separate requests as required by your application { allCars { make model } allOrders { id date } }
  22. MAKE WRITE REQUEST ➤ Apart from making read requests to

    your API, GraphQL can also be used to modify data ➤ Modification requests are called mutations ➤ Mutations can be used to create new data or change and delete existing records ➤ Mutations can also return data, such as, the newly generated order ID mutation CreateOrder($carId: ID!) { createOrder(carId: $carId) { orderId } }
  23. SPEED UP YOUR DEVELOPMENT WITH GREAT TOOLS ➤ There are

    a lot of powerful tools and libraries available that make using GraphQL a joy Graphiql
  24. SOME BEDTIME READING ON GRAPHQL ➤ https://graphql.org/ - the homepage

    of GraphQL ➤ https://www.howtographql.com/ - a great introduction to GraphQL ➤ https://www.apollographql.com/ - a popular client/server implementation
  25. SOME BEDTIME READING ON THE BFF PATTERN ➤ https://samnewman.io/patterns/architectural/bff/ -

    Original article by Sam Newman ➤ https://docs.microsoft.com/en-us/azure/architecture/ patterns/backends-for-frontends - An entry in Microsoft’s “Cloud Design Patterns”