 Okay, so hi everyone. My name is Ming-Fang and I'm currently an engineer at Facebook. And the title of my talk for today is Deep Dying to Relay Store. And so Relay is a library from Facebook, which helps you when you're writing on web apps and you need something to manage your data for you. And especially if you have worked with something in a React wall before, like React, GraphQL stack, there's a chance that you might have heard about Relay. It's an open source framework by Facebook. And for anyone that is not familiar, I try to keep my talk on, I try to explain the concept on high-level notes. But yeah, so before I start my talk, I want to really thank the organizers. I think these are great initiatives to share juniors and juniors in Singapore. So something about myself, the guys in glasses on the left is me. This picture I took like a few months ago, but somehow the shirt is the same. And also the things on the rice, like what I have come up with in the past few months, I think I have to thank the circuit breaker period for vastly improving my cooking a lot. All right, so before like diving into the internal of Relay storage, let's look at the big pictures and see how this piece of software fit. So a few years ago in 2013, React released to help us like write web as easier. So it introduces concept of components. You can think of your apps as a list of components. And the framework will figure out how to make the changes, how to render the changes for you. And two years later, Facebook released another project called GraphQL. And this is useful if you model your database in a graph manner. It's a different approach to develop web API. And finally, we can see that actually there are some pieces missing in the middle. And now we have the back and the front end, but we are missing some glue code in between. The developers still need to write a code to manually fetch the data to store it in the client. And then he has to manage the consistency of the data himself. So in that light, the framework I'm talking about today was born. And it's called Relay. It's a connector between the React UI layer and the GraphQL layers. And it was released in the same year as the GraphQL. So what is Relay? And so in short, it's just like the management framework built exclusively for if you have a React apps and a GraphQL server setup. So keep in mind that Relay will not work with anything like anything you throw at that. So only if you have like a wrap-based server and using a front end in React. So it's in charge of, Relay is in charge of proving out what kind of data you need to fetch, managing the consistency, and then present that to the UI layer. And we're going to dive into that in a few coming slides. Oh, the big idea of Relay, you're familiar with the front end application is that data is the core of your apps. And Relay is really co-locate the data with the components. So in the example on the right, you can see that you are creating a post. Then you really need some title and description. And this data dependencies in Relay, you can specify it alongside the component itself. So it makes it pretty transparent on what kind of data it needs. And you can think of your apps, you can think in a localized manner when you try to reason about the logic of these components. And one of the benefits that this model brings is it can actually make you be able to refract the code with easier, with more confidence, making it move faster, because you can reason about the component in isolation instead of like as a whole, as a part of bigger apps. So this talk is about the Relay as a framework, but Relay itself is not huge, but it does have like multiple moving pieces. The first part is the compiler itself. The compiler is in charge of converting the data requirements into a more understandable format. So let's go back to the previous slide where you see that the thing in red, really just the data requirements for these components. But this format is not very helpful for the framework. So the compiler will try to convert it into some data structure that the framework can consume. The second part is the meat of the whole framework is the Relay runtime where it actually managed the data fetching, storing the data and managing the consistency. The final part is the React Relay layer where it provides some helpers for us to work with React apps. But for the purpose of today's talk, we are going just to look into the Relay runtime. And more specifically, we're just going to look at how the data is stored inside Relay. Right. So let's start with an example to understand Relay better. Let's say in 2020 we're going to create a new social network. And you're going to do that, then you might need something called Post. The Post component on its own, the UI looks like there are several parts to it. The good thing is that we can always divide and concur this into smaller components. So for example, on the top, you can have something like account sections, you have the user names. And in the middle, there's a post contents with some titles, some description, maybe some photos even. And finally, you have like the reaction sections where user can leave commands, share the post. And the great things about thinking of your UI as a component is that you can always do this like multiple times. So let's say the post content is quite big. You can really spit it out into multiple subcomponents like, for example, text description or the attachment. So you look at this as a whole. Each component has its own data requirements. And the data requirements for exceptions is very different. So if you organize your apps in React as a tree of components, then naturally, the data of your apps will more or less look like a tree's too. The good thing about Relays is that why you're able to declare the data dependency per the components, but Relays on its own is going to think at the aggregation level. It's going to think on the app level. And it tries to aggregate all the data dependency of these whole component trees and likely just make one query to the server instead of like issuing multiple queries. Comparing this with a more traditional Raspberry API approach, you might need to have like to render one post components. You might have like one query for users, one query for the content, and another query for the reactions. So that's going to be more latency to this. Another approach with Res API is that maybe you can combine these three APIs into one, but this approach is quite rigid because it's not scalable because there are a lot of ways you have to combine APIs depending on what kind of components you're having. So in Relay, all of these are automated and the developers really don't need to think about that. Okay, so let's look more into how the data is fetched from the server into the Relay Store. On the left-hand side, you have something, you have a web apps or mobile apps, which is powered by Relay. And in other core Relay is a store. We call it the Relay Store. And on the rise, you have a RAP based server and it's powered by RAPQL. And when your clients want to ask for some data, it's going to ask, it's going to send a description of what kind of data dependencies that it needs. So it can be a very, very nested structure or it can be just like a simple like a JSON, flattened JSON file. And the server is going to read that request, pass a request and look into its database and then return the clients with the data it needs in the form that the clients asked for. So this data will finally be stored inside the Relay Store. All right, so for the store, then you can think of the store as a client-side cache. And it is basically a smaller version of your database. It's called sub-crap your database, but it's stored in a normalized manner. Relay is going to do some processing steps before saving the data inside storage. Okay, so to understand how data is stored in Relay, we need to look into two main data structures. The first one for Relay is called the record. The record is just a single entities with like an ID, a type and some other fields. Among these, the most important fields are really the ID and the type. The type let Relay know what the type is and the ID has Relay to identify this unique record. And in Relay, one record can be linked to another record, for example. In this field, you have like a user, but he can have an address and address is another record that the user can link to. The second data type, and I promise you that's only two significant data types in Relay, which is the second one is called the record source. It's nothing but just a dictionary with the key as the ID of this record and the value is the record data itself. And in fact, the Relay Store itself is just a big dictionary, a big record source. And every data on the client side see in this big dictionary itself. This data structure has another significant in that because there can be changes to the data store. All the changes are made to the store are expressed in terms of the record source. So let's say you're fetching some new data or you're updating some data, the results will be normalized into this dictionary line structures before it is submitted to the data store. Okay, so I talked about consistency before in the client side. One of the decision Relay made is that it's going to be normalized. And so let's look at an example here, like on the left hand side, the payload is the payload you receive from the server for the users. It has like an ID, a name for the users, and some nested field like address. But this is not how it is stored inside Relay. Relay will do some processing and actually separate out this JSON payload into two records, one for the users and one for address itself. And it's going to link up this record together. So as you can see here, this record is given an ID. And then the users will be linked to the address field instead of storing the address data inside itself. So the reason for normalization is that it's so much easier to maintain consistency. So let's say you don't have normalizations, you probably need to do more work to keep your data consistent. Let's take an example here. So I have two records on the left, A and B, and they all have the nested field called C. So for us, maybe you have two users who are in the same companies. Let's say one day the company changed the name. How do you update the tools? How do you reflect it in your apps? You don't have normalizations. What you need to do is that you need to find all the users that belong to this company and then go to pie its record and do the updates. On the other hand, if you have normalizations, that means you are, instead of storing your data in a nested manner, you are just linking the records together. So on the right, you have A is linked to a record C and B is also linked to the same record. And that's the difference. Then the updates become pretty simple. You just need to find the record C and then do whatever updates that you need. And this makes the change the update property obvious. The second advantage is that when you normalize the data, you are actually saving some storage. So on the left, you are actually storing two copies of the record C, but on the right, because it's just like you're linking the data together, then you only have one copy of C. So that reduce the storage overhead. All right, so let's look at the pipeline of how the data is written to the store again. Here we have, we also established some data from the server. They can come from the like the results of a query or you are updating some data or just having some optimistic mutation, which is a concept in Relay. But Relay will try to normalize this data into record source, which is just a dictionary and update in the store in this form. Then the change will be published to the store. The store will look at the payload and then combine the data received with like its internal data. Finally, the store will notify the subscriber for changes. But you can notice that so the most important thing about this diagram is that the publish and notify part is separated. When you're publishing the store, you don't immediately notify all the users, all the subscribers that something has changed. For some reasons, I will, for some performance reason that I'm going to talk in the next two slides. Here's a concrete example of like, let's go through the flow, some concrete example. So you have like data from the users here. And this going to be normalized into a big dictionary called a record source. And this going to be published to the store. The store will figure out what has changed. And then after that, they're going to notify your subscribers. In this case, it's your UI components that something has changed. Please go and update all the fields yourself. Here's one of the most interesting thing about the relay architecture is that the publish is really decoupled from notify. So the reason is that if you split, you separate these two processes, then you can actually achieve some performance because the store can actually combine multiple payloads before notifying any subscribers. So let's say you have a post and then there are two comments from your friends coming in. Then instead of like telling your UI so a bit twice, right, you can actually combine these two into one event, which is there are two new commands added. And the UI can just do the re-rendering ones. So that saves some computations. And so far, I have covered how the data is written to the store, but it will not be complete if you cannot read from the relay store. So now let's look at how we can achieve the data from the store instead. So the cool thing is that there's only two APIs when it comes to reading from the store. The first one is called the lookup. And since each component in relay must declare its data requirements, relay and convert this data requirement into something called a selector. So for example, here you have a post and the selector is the thing that I have like circle in red. And it's asking for a post with a certain ID. And what you're reading from the post is just a title and the descriptions. Then you use this API, then you get back from the store or the data in a form of something called a snapshot. And the second API is called a subscribe. And the API allows us to register a callback so that every time there's some changes in the store, it will tell us that something has changed. And basically, we can know whenever the events happen. So that's just about the two APIs for the read part. And one interesting architecture, I mean, one interesting optimization is that the relay try to differentiate what kind of events it should try to limit the number of events that are going to tell the components. So let's say you are having a post that listen to records three and four here. But during the update, from the server sent to the store, the store has recognized that only the records one and two has changed. So it recognized that there's no way the components is going to be interested in this change. So in skip that update, skip that notifications to the UI components. Then potentially, you can save some computations from that. So that's a quick rundown for me for the relay storage, which is JavaScript framework to work with the React and GraphQL server apps. And with that, I'm going to end my talk here. I also want to do a plug here where that our company Facebook is hiring. So if you guys are interested, you can go to the links here or just scan the QR code. Thank you so much for listening. And let's have some Q&A. Thank you so much, Min, for sharing about relay. Folks, if you have questions, you can either unmute yourself or drop them in the chat and we'll have Min adjust them. I'll give you people a few more minutes. In the meantime, just quite a quickly share my screen again. If I can find where my... Sorry, give me one second. I seem to have lost my Chrome. No, found it. Okay. So all right, folks, if you don't have any questions from Min, that's okay. But we'd really appreciate if you could give us some feedback about today's meetup. Hang on, whatever you want to call it. You can either go to the link at the bottom or scan this QR code and give us feedback, either for us as organizers or for Saranya and Min as the speakers. Tell us if there are topics you want to hear about or specific things that you'd like to get us, specific people you want us to get. Please feel free to add it in the feedback form and we'll try and address it as best as we can. If, yeah, I'll just leave it up there for folks to look at it. And now we have the floor open to just chat if anybody wants to do that.