Decision at Airbnb about Apollo, GraphQL Playground, GraphQL, Prisma, BackendDrivenUI

Avatar of adamrneary
Engineer at Airbnb ·
ApolloApolloGraphQL PlaygroundGraphQL PlaygroundGraphQLGraphQL

At Airbnb we use GraphQL Unions for a "Backend-Driven UI." We have built a system where a very dynamic page is constructed based on a query that will return an array of some set of possible “sections.” These sections are responsive and define the UI completely.

The central file that manages this would be a generated file. Since the list of possible sections is quite large (~50 sections today for Search), it also presumes we have a sane mechanism for lazy-loading components with server rendering, which is a topic for another post. Suffice it to say, we do not need to package all possible sections in a massive bundle to account for everything up front.

Each section component defines its own query fragment, colocated with the section’s component code. This is the general idea of Backend-Driven UI at Airbnb. It’s used in a number of places, including Search, Trip Planner, Host tools, and various landing pages. We use this as our starting point, and then in the demo show how to (1) make and update to an existing section, and (2) add a new section.

While building your product, you want to be able to explore your schema, discovering field names and testing out potential queries on live development data. We achieve that today with GraphQL Playground, the work of our friends at #Prisma. The tools come standard with Apollo Server.


23 upvotes·89.4K views

Decision at Airbnb about Apollo, GraphQL, Visual Studio Code, Git, GraphQLSchema

Avatar of adamrneary
Engineer at Airbnb ·

One of the joys I wanted to demonstrate in a GraphQL Summit talk I did is having so many helpful tools at my fingertips while building our product at Airbnb. This includes access to Git in Visual Studio Code, as well as the integrated terminal and tasks for running frequently-needed commands.

Of course, we also had some fun stuff to show for GraphQL and Apollo! The part that most people had not seen was the new Apollo GraphQL VS Code Extension. There is no need for me to copy over all juicy features from their marketing site (there are many!), but I will elaborate on one feature: Schema Tags.

If you are going to lint your queries against the schema you are working on, you will invariably be presented with the decision of “which schema?” The default may be your production schema (“current,” by convention), but as we discuss in the demo, if you need to iterate and explore new ideas, you need the flexibility of targeting a provisional schema.

Since we are using Apollo Engine, publishing multiple schemas using tags allows us this flexibility, and multiple engineers can collaborate on a single proposed schema. Once proposed schema changes for a service are merged upstream and those changes are naturally flowing down in the current production schema, we can flip back to “current” in VS Code. Very cool.


13 upvotes·82.3K views

Decision at Airbnb about Apollo, Figma, Zeplin, React Storybook, StorybookDesignStack, StorybookStack, ReactDesignStack

Avatar of adamrneary
Engineer at Airbnb ·
ApolloApolloFigmaFigmaZeplinZeplinReact StorybookReact Storybook

The tool we use for editing UI is React Storybook. It is the perfect place to make sure your work aligns with designs to the pixel across breakpoints. You get fast hot module reloading and a couple checkboxes to enable/disable browser features like Flexbox.

The only tricks I apply to Storybook are loading the stories with the mock data we’ve extracted from the API. If your mock data really covers all the various various possible states for your UI, you are good to go. Beyond that, if you have alternative states you want to account for, perhaps loading or error states, you can add them in manually.

This is the crux of the matter for Storybook. This file is entirely generated from Yeoman (discussed below), and it delivers the examples from the Alps Journey by default. getSectionsFromJourney() just filters the sections.

One other hack you’ll notice is that I added a pair of divs to bookend my component vertically, since Storybook renders with whitespace around the component. That is fine for buttons or UI with borders, but it’s hard to tell precisely where your component starts and ends, so I hacked them in there.

Since we are talking about how all these fabulous tools work so well together to help you be productive, can I just say what a delight it is to work on UI with Zeplin or Figma side by side with Storybook. Digging into UI in this abstract way takes all the chaos of this madcap world away one breakpoint at a time, and in that quiet realm, you are good down to the pixel every time.

To supply Storybook and our unit tests with realistic mock data, we want to extract the mock data directly from our Shared Development Environment. As with codegen, even a small change in a query fragment should also trigger many small changes in mock data. And here, similarly, the hard part is tackled entirely by Apollo CLI, and you can stitch it together with your own code in no time.

Coming back to Zeplin and Figma briefly, they're both built to allow engineers to extract content directly to facilitate product development.

Extracting the copy for an entire paragraph is as simple as selecting the content in Zeplin and clicking the “copy” icon in the Content section of the sidebar. In the case of Zeplin, images can be extracted by selecting and clicking the “download” icon in the Assets section of the sidebar.

ReactDesignStack #StorybookStack #StorybookDesignStack
8 upvotes·84.4K views

Decision at Airbnb about React Storybook,

Avatar of adamrneary
Engineer at Airbnb · is a straight up life-saver. It is the only screenshot testing tool I’ve ever used, so I would not be sophisticated enough to compare it to alternatives, if there are any, but the essential idea is that you push code, and it goes off and renders all the components in your PR, comparing it with the version on master.

This means if you edit a component like <Input /> it will show you the impact on components that use Input, including the Search Bar you accidentally modified. It. Is. Fabulous.

How many times did you think your change was contained only to discover that ten other teams started using what you built, and your change breaks three of the ten? Without Happo, you might not know.

Until lately, the only downside with Happo was that our React Storybook variations (the input to the screenshot testing process) did not always reflect reliable data adequately. Now that Storybook is leveraging API data, we can feel much more confident. Plus, as our demo explores, it is automatic. If you add a field to the query and then the component, Happo will automatically post the diff to your PR, letting the engineers, designers, and product managers sitting next to you see the visual consequences of the change you have made.

6 upvotes·62.4K views

Decision at Airbnb about HAProxy, Zookeeper

Avatar of stackbot

Early 2013

In early 2013, Airbnb tackled the problem of service discovery and load balancing in the context of a service oriented architecture (SOA) by building and releasing an open source tool called SmartStack. SmartStack is built on two other open source tools created by Airbnb called Nerve and Synapse.

Nerve is a service registration daemon that performs health checks that “creates ephemeral nodes in Zookeeper which contain information about the address/port combos for a backend available to serve requests for a particular service.”

Synapse is a transparent service discovery framework for connecting an SOA that reads the information in Zookeeper for available backends, and then uses that information to configure a local HAProxy process, which then routes requests between clients and services.

5 upvotes·15.2K views

Decision at Airbnb about MariaDB, MySQL

Avatar of stackbot

Airbnb’s web experience is powered by a Rails monolith, called Monorail, that talks to several different Java services. MySQL databases store business data and are partitioned by functionality, with messages and calendar management, for example, stored separately from the main booking flow in their own databases.

As traffic to the site continued growing, though, “one notable resource issue with MySQL databases [was] the increasing number of database connections from application servers.”

Airbnb uses AWS’s Relational Database Service (RDS) to power their MySQL instances, and “RDS uses the community edition of MySQL server, which employs a one-thread-per-connection model of connection management.” With Airbnb’s scale, this meant that their databases would hit the C10K problem, which states that “there is an upper bound in the number of connections that MySQL server can accept and serve without dramatically increasing the number of threads running, which severely degrades MySQL server performance.”

When an RDS MySQL server hits resource limits, users will have trouble connecting to the site.

MySQL does have dynamic thread pooling, but it’s only available in the enterprise edition; AWS MySQL RDS, though, doesn’t offer this feature, meaning Airbnb didn’t have access to dynamic thread pooling out-of-the-box.

After surveying several options, the team chose MariaDB MaxScale, which is “a MySQL database proxy that supports intelligent query routing in between client applications and a set of backend MySQL servers.”

Instead of using the MariaDB MaxScale off-the-shelf, however, they decided to fork it and implement their own version that would include connection pooling. Other MaxScale features, like request throttling and query blocklisting were implemented as well.

To enable horizontal scaling of the web application, the team deployed a MaxScale database proxy service in between app servers and MySQL servers. Through the service discovery system SmartStack, applications now “discover and connect to the database proxy service instead of the MySQL database,” allowing horizontal scaling to meet capacity demands.

Additionally, new Airbnb MaxScale proxy server instances can be launched to further enable horizontal scaling.

4 upvotes·895 views

Decision at Airbnb about MySQL, Kafka

Avatar of stackbot

The data-informed culture of Airbnb has been central to its success, and they have developed a sophisticated infrastructure to provide a reliable and scalable system for its users.

The basic flow sends source data into the system from two sources: a Kafka event stream and MySQL dumps from delivered through Sqoop. ETL and quality checks then happen in two separate Hive clusters, which are separated to isolate compute and storage resources and to provide “disaster recovery assurances if there ever was to be an outage.”

Partitioned Hive tables help ensure the data is immutable and reproducible, and Presto is used for almost all ad hoc queries on Hive managed tables.

4 upvotes·529 views

Decision at Airbnb about React, Redux

Avatar of stackbot

By early 2017, Airbnb was seeing around 75 million searches each day. In the midst of that growth, the team decided to rearchitect the web experience.

In the prior architecture, each page of the user’s journey, from searching, to viewing listings, to booking, was delivered standalone via Rails. The goal of the redesign was to maximize speed and fluidity.

In the new configuration, Hypernova is used to server-render React, and Redux is used for all API data and “globals,” like authentication state and experiment configurations.

3 upvotes·941 views

Decision at Airbnb about Apache Spark, Scala

Avatar of stackbot

In late 2016, Airbnb retired its legacy financial data pipeline. By then, they were transacting in 191 countries, with 70+ currencies and 20+ processors.

The new system decouples the financial logic from the product logic and allows for easier and more reliable horizontal scaling as transaction volume grows. It’s built on Apache Spark and store in an HDFS cluster. It’s written in Scala. They “chose Scala as the language because [they] wanted the latest features of Spark, as well as the other benefits of the language, like types, closures, immutability, lazy evaluation, etc.”

2 upvotes·33 views

Decision at Airbnb about Apache Spark

Avatar of stackbot

In 2015 Airbnb grew to a point that a scalable and distributed storage system was required to store data for some applications, especially search. Supporting low-latency personalized search was a major driver of the new architecture, as well as not having to index directly with the Rails and MySQL main application.

For this purpose, Airbnb created Nebula, which supports both real-time and batch access. The real-time part is powered by DynamoDB and the batch is a file format called HFileService, developed in-house at Airbnb.

Spark is used to merge all historical data together with the batch updates, with snapshots stored on S3. Nebula also can stream updates using Kinesis and Kafka, to keep other applications aware of the latest changes.

1 upvote·24 views