Duration 22:34
16+
Play
Video

Migrating to Apollo + GraphQL at Airbnb (BRIE BUNGE - Software Engineer at Airbnb)

Brie Bunge
Frontend Software Engineer at Airbnb
  • Video
  • Table of contents
  • Video
GraphQL Summit 2019
October 30 2019, San Francisco, CA, United States
GraphQL Summit 2019
Video
Migrating to Apollo + GraphQL at Airbnb (BRIE BUNGE - Software Engineer at Airbnb)
Available
In cart
Free
Free
Free
Free
Free
Free
Add to favorites
7.64 K
I like 0
I dislike 0
Available
In cart
Free
Free
Free
Free
Free
Free
  • Description
  • Transcript
  • Discussion

About speaker

About the talk

Topic: IT

You've heard that Apollo & GraphQL are amazing technologies that can help your organization build faster. But, what about all of the existing code that relies on REST endpoints? In this talk, we'll show how we migrated to Apollo at Airbnb. We'll cover our use of TypeScript, incrementally adopting GraphQL in our React + Redux codebase, and lessons learned along the way to help you make a similar transition at your organization.

00:35 Motivation

00:58 Overview

01:28 Status update

02:47 Migration strategies

06:08 REST to GraphQL

11:00 Goals and non-goals

12:00 Apollo HOC

13:25 Granular query fragments

15:54 Incremental adoption

19:13 Unified schema

Share

Hello graphql Summit and everyone on the live stream. Not your shirt with us the modern clients deck suppose you're at the point where you're 00:02 convinced the graph to all in Apollo are right for you, as you should be what you're looking at your code base and wondering how to get from point A 00:12 to point B. My name is Bree bunge, and I'm a front-end software engineer at Airbnb. I'd like to share with you some on the ground tactical tips for 00:19 migrating to Apollo graphql at scale incrementally and without regression. Changing the underlying data caching 00:29

infrastructure of a large code bases challenging. There's a lot of code to migrate and users who would be affected if anything were to go wrong. We've 00:39 been through the migration process on several things at Airbnb and collected lessons along the way that we hope to share with you in case you are 00:47 navigating a similar situation at your organization. First we'll recap the progress. We've made adopting graphql at Airbnb. 00:54 strategies reviews for migrating An exciting projects in the works that leverage Apollo and graphql. At 01:06

last year's graphql Summit adamary shout out in the audience their shirt. How are using Apollo and graphql to be ridiculously protective on the front 01:16 end. We made a lot of progress since here to bring these benefits to more and more teen. This year a small Scrappy team of Engineers from a cross 01:25 product and infrastructure banded together to rewrite our mobile web experience as a pwa or Progressive web application the new experience driven or 01:35 Miss games and Page load time and provided a much more intuitive experience for the user. We also used it as an opportunity to roll out more graphql. 01:44

As sections of the experience or migrated to graphql. We saw a steady increase in production traffic to our graphql Gateway. Mobile web with the 01:55 driving force here, but we also side option across our host tools on desktop IOS and Android Engineers are working on robots for their platforms as 02:04 well. Today around 5.8% of all production traffic on Airbnb is going using graphql 02:13 and that number will likely exceed 10% by the end of the year. Among the first products that surface is too and migrated 02:22

our search our product detail page and the booking flow. Work has already begun on a single guess platform with two Links 02:32 Drive productivity across 7 product surfaces in the guest flow. That's awesome progress. But how did we get there? 02:42 Let's look at some migration strategies reviews. The most common text after coming from for these migrations is a 02:52 combination of rest endpoints react and Redux and the amount of coding projects with migrated ranges anywhere from 30000 to 90000 lights. 03:02

What we'd like to use instead is react graphql and Apollo. We have a few options on how to get there. 03:13 The first is that we could rewrite a rap from scratch. This sounds awesome. Right? It's always so tempting, but it's rare that we get the chance, 03:24 but we have been lucky in some cases timing it with redesigns or the start of a new project. However, it's not always an option given time and 03:34 resources + the institutional knowledge in coded in a large app takes a lot of time to get right and unwind Instead 03:42

we could stop and ra Factor RF and we seen this work well on small or solo teams. The Risco that it's painful to reconcile Longleaf fork or feature 03:51 Branch when they're many developers actively working in the repository and the more changes we make and isolation means the more place for bugs to 04:01 hide and we don't want that. The final option reviews is an incremental approach. We found this to be the safest and most feasible option in most 04:08 circumstances. Give it a large team and a large presence in codebase. So let's delve more into how this is worked. We'll break down the process 04:18

into five stages our goal at each day is to have a shippable fully functional regression free version of our app along the way. 04:28 Before we begin some prerequisites. Will want a gradual and point on the back end. I won't cover how Airbnb move to graphql on the back 04:38 end. But you can check out this medium post on the Airbnb engineering blog if you're interested in learning more. The second is that we wanted to use 04:48 typescript on the front end because we can generate typescript types for Aquarius directly from the schema, which is a single source of Truth between 04:57

the back end and the front end. We saw typescript as an absolute must in order to take advantage of end-to-end type safety development is faster and 05:05 we have more confidence in what we're building. We want to customize cogeneration command internally, but this is what you'd run is part of a Apollo 05:14 stooling this example shows a gradual query along with the typescript type that gets generated by Apollo stools. Will you please type 05:22 in her code to make sure we're using the right values and have all of the necessary Nail Trix? Typescript is now the official language for web 05:32

development at Airbnb and over half of our 3 million line code base has been migrated so far. If you're interested in learning more about our process, 05:40 you can check out this graph you all distress comp talk from earlier this year. When we're introducing graffiti on Apollo to our projects, we first 05:48 run an internal migration tool to convert R code from JavaScript to typescript First and the stock covers that to a little bit more depth as well. 05:57 With a gradual and point on the back end and type scription place. We need to swap out our rest request for a graph to our request. As a side note, I 06:08

will note that Paula Lyncrest is an option that allows you to use a rest endpoint with Apollo spreading libraries. We prefer Degrassi one point though 06:17 in order to get typescript 8th generation and smaller response sizes viafield selection. We might consider it if exposing a gradual and point is 06:25 simply not an option. The goal at this stage is to verify that are front and back in Immigration is working as expected and to generate a script 06:34 site. We won't make any changes to our react components or change the shape of the API response the stages just intended to affect where we get our 06:44

data from not how it's used. Let's use our homes checkout flow as an example. There is an endpoint for creating a reservation 06:53 that has been exposed as a graphql mutation. We make a request using the Apollo client directly at the same point in the code where we were previously 07:02 making our post request. The first thing to note here is that we said we're going to keep the API shapes name. So we need to construct a graph to a 07:11 mutation that corresponds to the data that we were previously getting back from our rest endpoint. Let's see what that response looks like. That's 07:20

that's a lot of Json over fetching. 07:29 Ronaldo our goal is to construct a graph to a query that corresponds to this data. We could try to eliminate Fields now, but will likely break 07:39 something cuz we're not sure which fields are actually in use. Graphql requires explicitly declaring which field we need from the API. So we'll need 07:47 to exhaustively list out every one of these fields from a graph to a schema to match that response. Doing this by hand would be tedious and 07:57

error-prone fortunately, we can Leverage The graphql schema itself to help us out. Another place where we've seen the graphql schema and uses the 08:05 grass field playground, which is an awesome developer tool that makes use of the schema for auto complete until tips is very helpful when you're 08:15 offering a query behind the scenes the playground issues this introspection query against the graphql server to get information back about the fields 08:23 that are available we can use this information for our purposes to recursively unpack the schema. Cuz what we're trying to do is like a programmatic 08:32

version of Auto completing at every level along the way. Another single keep in mind as a lesser-known feature of graph to all that you might find 08:40 helpful gradual a listen to arbitrarily rename field in a query we found this helpful because it's supposed to field as snake case 08:49 and are exposed in the camel case. So we can use anything to actually convert the case as part of our query and this would get carried over into the 08:59 generator typescript types as well. With these ideas in mind we wrote a script to generate an epic 660 line mutation for the 09:08

homes check out flow with the approach if you're curious more about how this work. We've been run Apollo co-gen to generate typescript 09:18 types for this mutation. This is incredible. We get thousand lines of type straight from the schema. This is such a dream compared to how we do it 09:28 before we would look at the response right up the pipe by hand. It would have mistakes that we get out of date very quickly if the back end changed, 09:37 so this is just a dream. I don't think I noticed here is Lisa. Function. There were slight differences in our 09:45

request and response format on the back end. So we created adapters on the front end adapter here doesn't mean anything graphql specific. It's just a 09:55 utility function that transforms or dabs an object from one form to another for the inputs. We made sure that the adapted request match with the graph 10:02 to a land point expected. And for the outputs, we made a request to both the rest and gradual and point and recursively this the adapted version of 10:11 the response to make sure it exactly Matt what we were receiving before. These investors will be removed at a later stage, 10:21

but the intention for now is to keep all of the codes surrounding this API call the same. At which days we 10:30 have a Superbowl at so we can pause here ship it and are Apple still work. The next thing I want to do is 10:40 propagate our shiny new typescript types throughout our code. The goal of this is to make sure that the generative types to use the generator types 10:50 because they increase confidence at later stages in the migration process will get compiler errors when things don't line up. We're not going to touch 10:59

any runtime Behavior here. We're only editing the types. We go through our code and replace all occurrences where we had in any type or no type or 11:06 manually created one with a generated type from Apollo. Awesome, as these types are a common issue. We've run into his having to do 11:16 deep no checks like this one. Thankfully, there's a pet Indian package with a bubble plug-in. You can use call Dy DX that lets us express this id 11:26 idea much more and concisely while still being fully type safe. And I guess it's just a stopgap until JavaScript support optional 11:36

chaining which is currently a stage 3C c39 proposal and will be included with the next version of high school. We can't wait because it lets you write 11:46 code like this instead. Before we were using the Apollo client directly to make our API request now, 11:55 let's make our code more idiomatic by using the react hsc's exported by Apollo. Did I say a chassis Ironman hooks? 12:05 Hawk Hawk anyways the recent Apollo react hooks package get us some new functions to use. We love books Airbnb because they're 12:15

easier to reason about there's less boilerplate and they work better with typescript. We're still using Apollo waitress. He's right now, but we're 12:25 actively upgrading to use hook. At this stage our app is using the Apollo client, but we're still firing Redux actions and components are using to 12:32 read UPS Store. Apollo takes care of betta fishing with loading an error States so we can wean yourself off of Redux for this purpose. 12:42 We were Factor app to use Apollo's HR Caesar hooks instead and update are components to use data from the Apollo cash rather than the Redux store. We 12:52

need to keep the Rita store around for now though because it's still sore some information not yet in the Apollo cash, but it's world has been 13:02 diminished. What are the benefits of graphql is reducing over fetching because clients specify exactly the feels they need 13:09 we missed out on that with our Mega query. So let's fix that by introducing more granular queer fragments. At this stage are 13:19 clear lives in our top level at component as represented by the silver Acura logo, it contains all Fields required by all components all the way down 13:28

the tree but the best practice is to specify their own crew fragments because it called locates the data needs with a code that actually uses the 13:36 data. It reduces over fetching and promotes code reuse because fragments can be sure to crossword. We start at the Leafs. 13:46 These are the components closest to what ultimately gets rendered so we can trace through it and determine what fields are actually in use and add 13:56 them to its for a fragment. We rerun cojin to get types for our new friend mint and use these types in the sub tree of the code. We can actually use 14:03

typescript to help guide us here. Because if we've missed a field in our fragment will get a typescript are at the Houston site where it's missing. 14:13 We've been composed this fragment up into this parent component and one little further up back into the app component. This is a gradual change. So 14:23 we're not done yet. But we have a fully-working app and can verify the changes. We just made in isolation. We rinse and repeat this process until our 14:31 whole tree is covered before the app had an honest and clear that knew about all the data used by all the components in the tree. But now our top of 14:40

Aquarius simply a composition made up of its child fragments because the fragments are declared in close proximity to where they're actually used we 14:49 can be confident. They're only fetching the day that we need. Once all components have been migrated to Apollo we can consider 14:57 what to do about the remaining Redux state. We found that any state we were snoring in Redux could be sufficiently managed by Apollo for API data 15:07 and reacts local state or context for client data while considering Apollo's client local resolve more complex client data use cases. This 15:17

is consistent mental model for handling client data. We use reactant Apollo for Allstate rather than fragmentation between react and Redux. Moreover 15:27 we found that we wrote quite a bit a boilerplate when using the extra things that Apollo just handled out of the box. So we could delete substantial 15:37 amounts of code when migrating to Apollo and Apollo handled cashing more effectively than are hand-rolled solutions did anyways. With all of these 15:43 stages complete we end up with our desired result of an Apollo and graphql powertap. That's a hundred percent typeface with no over fetching and we 15:53

kept the site up and running throughout each stage of our migration Journey. With graphql powering more of our code 16:02 their exciting projects that were actively pursuing to take advantage of this new data fetching later. I like to share two of them with you today. 16:12 The first is service worker query prefetching. The goal is to kick off the grass go according request as early as possible. So users see the page 16:24 rendered with data sooner. Shout out to Cali Riggins who is leading the charge on her mobile web service worker implementation and is pursuing this 16:33

novel idea. Here's a side-by-side comparison of a server-side render page on the top and a page loaded via service worker on the 16:41 bottom. If we don't have a service worker or pages are service. I rendered there's a long gap between the page while the pages loading before we see 16:51 content. With service worker on the other hand and application show shows up right away and allows the user to get oriented to the page while the 16:59 content is coming in and the pace was faster because more of our JavaScript is cashed. Here's a profile of a request filled by server-side 17:08

rendering. We start with the server request. This is when the server-side rendering happens in our graphql request is made on the server. Then we 17:18 parsley its Gmail and downloader JavaScript at this point the page becomes visible using the HTML that was rendered on the server and once react 17:27 hydration completes our patient becomes Interactive. Here's a profile of a request fulfilled by the service worker at Shell. 17:36 The service worker immediately fulfills. The request JavaScript is loaded from the cash and we start some initialisation the shell becomes visible 17:48

react hydrates then our request begins. These are see the loading State until the request completes then our page is Interactive. 17:56 There's a gap year though between when the service workers started for filling a request and when the grass to request begin, there's a significant 18:07 optimization opportunity here. We can register our queries at the route level instead of at the component level. Then the 18:15 service worker could kick off the gradual request right away because it's decouples the react rendering from when we can read the query in this 18:25

particular instance that would have saved is 400 milliseconds. It means either would have been able to interact with his page 23% sooner and that 18:34 request that affect size is even larger Force lower devices. We tried this with six xcp you slow down so we can see the pages 50% sooner. This 18:43 performance when is huge and with this primitive of being able to load data just given the URL we can do other fancy things like pre load data for any 18:53 link on the page and all of this is happening off of the main thread. I'm going to project we're pursuing is a unified schema 19:01

and Shadow to a ruin in the audience who's been building out the system and piling it on the trip planning team. Do you understand? The problem in 19:11 this project is solving let's first look at Airbnb is service oriented architecture. Are back in services are broken down into three main categories 19:20 of data and presentation Services encapsulated data model, like a listing or user and drive data services combined 19:28 information from multiple data sources, for example, a listing card combines user and review data. Presentation Services encapsulate the logic of an 19:38

end-user experience clients call presentation services to get the data needed to render the page. Currently our graphql schema is service Centric. 19:48 All of the top-level keys correspond to presentation services. This was a concession we made so that graphql would be more compatible with our 20:00 particular service-oriented architecture strategy. So now that. You'll see more traction internally we're revisiting this design to make it more that 20:08 eccentric. The new schema would expose a unified graph that is more sensible for clients and would enable better client-side cash utilization 20:16

because more entities are shared across queries. The same services are used behind the scenes, but it's more or less isn't implementation detail. 20:26 To make this happen or data-centric schema better. It's out to services that hydrate the data requested by the client the date of hydration code 20:38 defines how to load objects by their ID. Centralizing are hydration logic reduces the amount of code that we saw a duplicated across many of these 20:47 different presentation services. moreover we can improve data fishing efficiency There are cases where the same data was being loaded at 20:55

various levels in our presentation level layer. This is an example trace for my query made by our product detail page each bar here represents a 21:05 service call. And the 10 purple bars represent redundant data fetching for the exact same listing. We 21:14 can reduce state of catching inefficiency by bashing and cashing request that the centralized hydration layer. That would have meant only hydrating 21:24 that listing date at once. This work is in beta, but we're encouraged by early results and have certainly we will certainly have more sugar by the 21:32

next graphql Summit. I'd like to leave you with a few key takeaways. When Apollo 21:42 is paired with typescript, you can build and migrate code was significantly more confidence that nothing broke along the way. Consider the options and 21:52 decide whether an incremental adoption strategy is the best approach for your situation. If you need to change a large pre-existing code base and keep 22:02 it up and running and every step along the way. Finally Apollo and graphql or a client data foundation on which you can do amazing things and I can't 22:09

wait to see what you all build next. Please come find me or any of the other Airbnb Engineers here. Who would love to talk with you more about any of 22:19 this. Thank you so much. 22:28

Cackle comments for the website

Buy this talk

Access to the talk “Migrating to Apollo + GraphQL at Airbnb (BRIE BUNGE - Software Engineer at Airbnb)”
Available
In cart
Free
Free
Free
Free
Free
Free

Video

Get access to all videos “GraphQL Summit 2019”
Available
In cart
Free
Free
Free
Free
Free
Free
Ticket

Interested in topic “IT”?

You might be interested in videos from this event

September 28 2018
Moscow
16
122
app store, apps, development, google play, mobile, soft

Similar talks

Adam Zionts
Engineering Manager at Apollo GraphQL
Available
In cart
Free
Free
Free
Free
Free
Free
Evans Hauser
Open Source Engineer at Apollo
Available
In cart
Free
Free
Free
Free
Free
Free

Buy this video

Video

Access to the talk “Migrating to Apollo + GraphQL at Airbnb (BRIE BUNGE - Software Engineer at Airbnb)”
Available
In cart
Free
Free
Free
Free
Free
Free

Conference Cast

With ConferenceCast.tv, you get access to our library of the world's best conference talks.

Conference Cast
505 conferences
19653 speakers
7164 hours of content