Slide 1

Slide 1 text

BACKENDS FOR FRONTENDS WITH GRAPHQL Pavels Jelisejevs

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

BACKENDS FOR FRONTENDS

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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)

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

GRAPHQL

Slide 17

Slide 17 text

“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 …

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

PASS PARAMETERS TO FIELDS { allCars(make: “BMW”) { make model } } { "data": { "allCars": [ { "make": "BMW", "model": "2002" } ] } } Request Response GET/POST Request

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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! }

Slide 24

Slide 24 text

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 } }

Slide 25

Slide 25 text

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 } }

Slide 26

Slide 26 text

SPEED UP YOUR DEVELOPMENT WITH GREAT TOOLS ➤ There are a lot of powerful tools and libraries available that make using GraphQL a joy Graphiql

Slide 27

Slide 27 text

WRAPPING IT UP

Slide 28

Slide 28 text

TAKEAWAY #1 THE API SHOULD BE DESIGNED FOR THE NEEDS OF THE CLIENT

Slide 29

Slide 29 text

TAKEAWAY #2 DIFFERENT CLIENTS NEED DIFFERENT APIS

Slide 30

Slide 30 text

TAKEAWAY #3 GRAPHQL ALLOWS YOU TO PUT THE CLIENT IN CHARGE

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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”

Slide 33

Slide 33 text

THANKS!