 So hi guys The talk I'm going to give tonight is called no rest for the wicked But actually it's just an introduction to GraphQL So some introductions first my name is Jew I'm an engineer at alphasites and build ambitious apps in ember So talk to me if you want to know more about that So who knows what the GraphQL is has heard about it half-and-half say yeah, so GraphQL GraphQL stands for a graph query language It was invented by Facebook in 2012 and now it was made open and it powers most of the Facebook native apps So it's called GraphQL which stands for graph query language, but I think what they should have done is to add this So it doesn't actually require a graph. It's called GraphQL, but you can it's back-end agnostic so you can use everything in GraphQL you can use your Postgres you can use actual like graph database you can use no FTP I guess you can use if you really Like risk you can use something like MongoDB Was this okay, so I was thinking we can start with a very simple example on Just like how GraphQL works So if we have a table like this, it's called users It has ID name Twitter handle age and country and It's a very simple table. Also. We know the will is a vampire There is a very easy way to get all the users in this table and this is Called a string because actually is a string so usually GraphQL has only one endpoint and you send a payload to it Is this normal? Okay But I can change it if you want to In one click yeah, is it a challenge maybe three is it fine Let's try this To white oh my god, maybe this is better. Well, I think this is better Yeah, good Yeah, so I think it's fine. So okay So I'm trying to fetch the users and of those users. I want the ID and the name and this is a result I have data. There's a users inside and there's the fields have asked to the GraphQL endpoint So which is a bit weird is that we're sending A string here and here we're getting adjacent response, which is okay. I mean So let's try to do something else We're passing some fields now to the GraphQL endpoint and we're asking only for the user Which ID is one and we still want the idea in the name and the GraphQL endpoint just returns like this to us It's pretty simple Obviously we also want to create Users so which is different in this example is that we start the query with this little keyword Which is mutation which indicates that we actually want to make some changes in the database. So we say, okay, I'm going to use this Thing which is called crazy user I'm going to pass a name Tom Twitter handle Tom Dale country USA and I want the ID and the name of this newly created record and I want you to assign it to a field Which is called user and the GraphQL endpoint return something like this Obviously there will be errors and for example, let's say in our example the name is required and you forget to send it and The API will return something like this. Let's say, okay, you've tried to Create a user, but you didn't pass anything for the argument of type name so usually when you're defining the schema on your GraphQL endpoint you define what is required what should be passed what cannot be passed and Usually the errors are really good, especially compared to a normal API where you have to do all the dirty work So all this was really simple, but as always relations chips make everything more complicated So if we have another table she's come company and they're alpha size and Roku and Here we add a company ID to each user in this way we can send Queries which are a bit more complicated. So for example in this case I'm still asking for the user which ID is one But now I'm interested in his ID in the name and then on the name of his company So in this way, basically, I'm telling that endpoint. I actually want all this information in the same payload who and The endpoint will return something like this. So it just like does everything exactly as you would expect Something a bit more fun is actually we can repeat this process So for example, I can ask for this user with this ID I can ask its ID the name the company and for that company I want the name and for that company I want all the names of his users and I want the endpoint to assign it to the employees field So the endpoint will return something like this So data user ID name company office as employees and if you notice something It's quite striking the similarity of what I'm asking for and what I'm receiving. It's exactly the same thing So I think I mean Well, I should stop like shocking you like this So why should I use it if you read through all the Facebook? articles they will you read like use a lot of these buzzwords Usually my actual response when I read any of the words in this page is something like this So, yes, it was really really hard for me even to read the articles because every three sentences It would use this really really Buzzwordy words, which I think a bit. Yeah And this is my normal response and then I can't just can't take it anymore You'll see like this dog what it does when you can't take it anymore. It's just like guys So too much about the word. I just So Instead of using all the buzzwords, they thought well, maybe I can just do just like explain why I think GraphQL is Amazing and I'll just start from the title of the talk, which is no rest for the wicked and I mean who likes the good guy Right, so let's say we have a rest request get users one So what's going to be the response to this request and the thing? Is we don't know we have no idea. I have literally no clue what the response is going to be like Our only way to is to like understanding that is to load up a documentation If there is one if there isn't you have to open up the source code Or you just try to call it and then look at the payload in the Chrome inspector Instead if I see something like this a GraphQL request and I'm user of the idea of one and return me the idea in the name I can pretty much predict. This is going to be the response So you can see like there is like a striking similarity between the shape of the request and the shape of the response they have the same shape and It's like and this is something I think we've always taken for granted that it's not possible We don't care about that because I mean I'm just talking for myself, but I've Started programming as a Rails developer. So I feel the rest is like part of my blood in some sort um so there's really like cool programming concept which is called what you see is what you get and I Think it's Really really nice when you're working with something because you have no surprises what you're going to get and If you want to be a little more sophisticated about this is every time you're sending a GraphQL query. It's actually a Contract between you the client and the back end And what's more interesting about that? It's it's not only a contract, but you decide a contract. So you the front-end developer you're Setting up a contract with the back end and you're driving the whole thing So you can basically ask the back end to do a lot of things for you You can ask him to alias fields You can do a lot of things and the back end would probably just like do that There's this concept which is very well known. I'm sure most of you know this which is called like solid They're like good like object oriented programming principles, and I'm sure the someone of you knows what the I stands for No, and that's one no come on guys Everyone would know at a Ruby meetup. Well, anyway It's called interface segregation principle and when you're studying like of your rented patterns and your programming Ruby or like Yeah, I don't need this. This is mostly like meant for Java interfaces But what I want to do is I'm just trying to Read aloud some of the concepts of the interface segregation principle and I want you to think about rest and GraphQL So it says clients should not be forced to depend on methods. They do not use Many client specific interfaces are better than one general purpose interface The dependency of one class to another should depend on the smallest possible interface Make fine-grained interfaces that are client specific. Okay So Let's go back again to the example, right? I'm just using this totally Random service where you can post repos to and I'm sending this rest request to this endpoint I'm creating a new repo And this is the actual payload they get back You can't see it right because there's so many fields. You can't really see anything of it There's like a lot of URLs and a lot of information of the owner of the repo If we try to do oh, exactly, so I like to Give like a bit more character to rest and ISP So instead if you think about a GraphQL request is something like this, I'm creating a mutation I'm creating a repo name description home page private has issues as weakest downloads And I want you to return me the ID you name the clone URL and the avatar of the owner But assign it to a user because I don't care. I just like I want you to call it user for me and The API endpoint will return something like this Well, if everything goes successfully that is if it doesn't it will tell you exactly what went wrong What you missed and what was required all these like as soon as you define the schema So you don't have to write your own code to handle all these errors, right? So the endpoint returns something like this so basically GraphQL loves the ISP and What is like it just means what does it mean is that every time you're writing? GraphQL query, you're just like creating one very client-specific one Interface which is very client-specific which just for that page And it basically means that every time you can write a different query It will create another interface and you can create an infinite number of them when whenever you're creating a new query But yeah, I mean it's just like if you talk about principles I think it's really really easy to think oh, it's a principle So you must be true and I guess in natural reactions like well, I don't care about the principles I just want to build code who cares about ISP. I've never heard it before right But I think that if you just like stop for one second and think about how you develop amber applications You realize well first of all ISP has been stew. So please don't be too mean But let's say you have an article's endpoint which returns some articles for newspaper and in the front page You want to display related articles for each article So well, it's easy, right? You add them to the payload So every article will have some related articles or a list of IDs of related articles and this will fetch other articles, right? And now every time you have to use in any way the articles endpoint You have to pay the performance price of either serializing all these other objects or at least Running some queries to fetch them from the database and just return the IDs So there is no way you're not paying the performance price every time you're using that But what if you could do this You could just like ask for articles is just say okay for these articles I want the ID the title excerpt the preview image I want the name of the author and I want five related articles and of them I just want the title and the preview image and This will only apply from the front page So every other time you're using the articles you're not paying the performance price and there's no way that someone who just joined your company and Needs something for an API and add something slows down the rest of the whole app Because they just like doesn't happen There's another So hopefully I got you a little bit interested in GraphQL But as we all know GraphQL has been made by the devil So can we actually use it in number? and The answer is yes, so we've written we've wrote this Adapter for ember data and it's called ember GraphQL adapter and It does some like a couple of nice things. So for example, it automatically generates queries and mutations It supports field and object and aliasing. It supports async relationships It's fully supports belongs to relationships and it sort of supports has many relationships We still haven't decided how to handle them properly So You basically import the adapter So it's nothing fancy and then you import the serializer as well and then you have a model which is Has a name you fetch all the companies from the store the Eddon will generate a query like this will send this query to the GraphQL endpoint the GraphQL endpoint will turn something like this The serializer will convert this into just an API payload so that ember data can just Munch it and it will work So the cool the really cool thing about the whole setup is I think Just like everything I've said is possible just because of how ember data is well built So for example right now we're using this in production But we don't have the time to convert all these resources to GraphQL But we have one resource which is using GraphQL and it has Relationships with other type of resources which are on JSON API and some of other than our own rest and they still Communicate between each other using async relationships and you can when you open the inspector You can just see them like loading up from different endpoints But in the app it just like works automatically You don't have to risk like you don't have to pay the cost for the whole trends transition and so you can just replace one resource and you can try it out see how if you like it see how it makes sense to you and So I don't think anyone has like an actual excuse. Oh, I have to port every no you have just have to try one single resource and On the back end there's this like reference implementation made by Facebook, which is called GraphQL JS Well, we are using on Ruby's this jam, which is called GraphQL Ruby, which basically Gives you the ability of exposing this GraphQL endpoint. You can specify the types. You can specify different types of queries of mutations You can provide callbacks. You can you can basically do a lot of things which are written in the GraphQL specification and Also, I've just added a couple of references to I think the first one is the best resource to actually learn GraphQL. Then there's the Facebook Page about it. There's a Hacker News thread where one of the authors replies to every type of question and These are some of the articles I've read which are really good and these are three videos I've seen So maybe I was thinking if I have time I'll just show something really quick, which is this tool, which is called graphical and Using this tool you can play with GraphQL so it's completely client-side so you can do things like For example right now I can do this here. I Want to show all the authors the name and the Twitter handle and also use this introspection to see to show you Basically, what are the possible types of things that you can do? so for example in the you see like usually in In GraphQL it's really important to distinguish a query which is just read only and a mutation which is writing on a database So for this block schema, there's posts So you'll see okay. This is the post I can pass a category category. I can ask for the latest post So for example, I could do something like this Latest post and I want the title of the latest post new feature tracking error status with Kedira or I can do recent posts recent posts count five or Recent post count three. Oh, I refreshed those Okay, they still work and also you can create mutations. So as I said before you can do something like create No, I have to type mutation in front and then create author and then I can say okay I'm using this ID just to and I want to pass a name Which is too as well and of these objects. I want back the ID, let's say and If I run this will say okay create author and see like this one It just like returns author, but I could assign this to something else, right? So you could say Jew is this create author, but if I rerun this again, you will say Actually you try to create this but this isn't didn't work because this author already exists and will tell you Or for example, if you try to do something like Hello Maybe here You will like This is like a bit too big, but I will say like something like really explicit. So Unknown argument hello on field create author of type block mutations You don't get this when you're using JSON API. I think but and It's just like you can see like how much easy is to track down all these like little small incompatibilities between the front end and the Back end and it's just like I was never a fan of like type systems in this case I think it makes perfectly sense Because like you spend like countless amount of times to try to coordinate the front end in the back end and This case everything is handled for you It is like you see like this one the first thing is what I passed which wasn't not like wasn't like the back end Couldn't recognize and then it also told me but you should have passed the name to me and you didn't and If you just like I'm trying the sandbox you can try out all these different types and mutations you can just like gets just like see how it feels like and They and if you follow the course, which is exactly on learn graph scale, it's really good and it goes through like all the possible things that you could do with it and it's also like goes like more in detail and how it works what was like the reasoning behind it So I think that's it good. You can find the sites here and There's the the adapter Yeah The service what what methods are available? Yeah, exactly. So basically you can you can ask There's a keyword she's called underscore underscore type and then you can ask I Think it's you can read here type I Don't know if I can read there, but basically it's the same thing as you're seeing here on the right So you can ask for like for example for a post what is a post and will return something like this So and it still respects the same graph QL Syntax so you can extract the fields you can just like get only the names or if you want to get like their dependencies Their arguments you can just like fetch them in the same way as you fetch your normal data But you can introspect all the types and see how like what they do expose Something I haven't said which the Facebook guys are super proud of is that if you're using graph QL Basically, you don't you will never have version in anymore because as soon as you introduce A field to your API. It will be there Forever if you want to if you want to add a new field and you want to deprecate an old field You can deprecate it and this will keep the old field still working But when you do introspection you won't show it anymore. So we won't show the new field anymore so if you think about If you have the central API and it powers Hundreds of different applications How many versions of the API can you have like in a year 15 20 a hundred who knows But instead if you use something like this You still like maintain restore compatibility and then as at some point when you're shorter No one ever is using the field anymore then you can remove it But still it's all completely transparent and also the client can do already some of the work because if you want to rename some fields You can still pass an alias and just change your query and it just like works. You don't have to coordinate anything and And it works like a very High granularity so you don't have to switch completely an endpoint You can just like change what has changed there if you just want to obtain the new field Which is improved and has like some more capabilities But yeah, I was super impressed by this tool just like to how see how it plays out and it's pretty fun Yeah Yeah This page Exactly This is a really good question because exactly what we're doing right now in the add-on is just Enumerating all the attributes right and then we create this payload. We just like send it. So it's a bit anti Idiomatic right because they're all about just ask for what you need and we actually have all the fields in the ember data model Even there I think it's still better because we just send Like we just like ask for these fields. Well right now we get all the fields anyway But apart from that I think what could be improved what I'm planning to do is to add this support when you're setting on a Relationship between objects to be able to tell that I want this other Object in a relationship and I only want these fields of this object So it overrides basically all the attributes in the ember data model But just like giving precedence to this list of fields You've just specified and I think it's super useful because even if you're using async relationships in ember data it you're still loading a lot of stuff you don't care about most of the times and it just it feels weird and Over time it's dangerous because people will have will need more from a certain endpoint We will add those fields to that endpoint You will have to pay the price even though you shouldn't pay the price because you're not using those fields And especially like right now everybody's going towards microservices, right? So you're using the same API in 10 different apps and 10 different apps have their sort of like own terminology if you have their own necessities of what actually to load and You're always like fighting and making like right now in my company I have to play the role of the gatekeeper of that API because I don't want anyone to make it slower And it should be but instead if we had a graphic on that endpoint I wouldn't need to I wouldn't need to do that because if you want to load more stuff and you want to make your apps lower Yeah, it's okay as long as the rest of the other like 10 applications don't get slower So I think this like we've given for grant we've taken rest for granted for a long time But the more you try to go over a service oriented architecture You feel this pain every day and what they do with a graph KL Apart from all the syntax and nice things They're just like inserting these layer in the middle. So for example, I've heard this talk by and I think I've added a link here Oh, yes, it's here. I've heard this talk with this guy who Worked and reworked financial times website And the he said they had like 10 different APIs in the back end and five front-end apps And this each one of the front-end apps was like sending a lot of requests to different services And instead now they just sent to the central GraphQL endpoint, which then loads stuff around but it's a huge advantage and Even though it was made by the devil, I think the devil has like a lot of Tools at his disposal Exactly exactly My main problem with Jason API is that it could do all these things but it doesn't so for example it includes and possible like fields you want to extract they're part of the specification but Like I think like it's they're not really being pushed, you know They're they're part of the spec because someone thought it was interesting to have but Even if you see the syntax that you use in Jason API to do this, it's a huge string So if you think about making something a bit more complex just becomes completely unreadable, right? I think that when you see something it's just like under engineered for this purpose And instead when you read the J GraphQL query, it's just like the right way It has the right feel and then you see the shape of the request. You see the shape of the response It's exactly the same shape if you see the Jason API request is still sort of It's like it doesn't it doesn't feel right Well, it's going to be part machine but you are not the machine right But when you're especially when you're working we're developing very often You want to see how stuff is like what the thing is doing you You still have no idea most of the times anyway about like what the computer is doing But at least when you get a chance to see the thing and you compare there's like, okay this makes sense and Instead what I feel like in Jason API is exactly they're trying to make a protocol which is readable in my machines But I have to work with it unfortunately and just like doesn't feel right to me But I don't know if it's like something person But there's a lot of people I've spoken with I feel like Jason API is too verbose. It feels like soap. They said soap and And like in something else for example, which I think is really cool in GraphQL It's like you have the capability if you want to to just write one giant GraphQL query, especially if you're developing a native application and that query just loads everything You don't have to have links to go around go back and do all this sort of stuff and that Giant payload is actually going to be used just but that part of the app or by that specific app It's not going to slow down anything right like anything of the other apps that you have and I Know it's a bit of a pity especially in ember because like all the adapters for example Jason API compliant, but there's since it was like Written in such a good way. You can just use a serializer to port your own representation into the Jason API compliant representation You just take that Jason API as the ember Specification and I'm perfectly cool with that But if I have to work with that on a daily basis and try to get the right gem on the back end to do Jason API in the right way and getting on the on the payload it just like too much for me And I couldn't do it You know by example When you request, let's say 50 articles and each article has an author. Yeah, this happens to happens to be the author of many of these articles is this Do you have this information duplicated inside each article or you have this article? Sorry this author in the rule level only once and it's referenced by You can specify them separately so for example in all the examples I've said there's only one graphical query, but actually you can specify multiple of them and actually GraphQL will try to be smart and try to Basically compress the data If you don't want him to compress the data you can pass some aliases in order to tell him Okay, no, actually, I don't want you to compress the data Just like give them back to me separately one to one a very valid concern is Since you're writing a query, right? You're basically writing SQL and you're writing this SQL which is open to the world So you could write a really really long and complex query which crashes the database like theoretically, right? so I think the Facebook guys what they do to do that is They assign a cost to each query and if they have this these these query gets Transformed parsed and transformed into an ST and they evaluated the cost of the query and if it's too big They just thought you don't do it. It's just like return something say The thing is actually like too expensive. We can't do it or another idea was just like to do a timeout So if it takes more than five seconds just abort or something else is just check Like how many because the the main problem is just like the nesting right so you can just say okay if you're trying to do more than three Nestings just like give up because you won't be able to do that. I think something else which is bit left also a bit Open on the spec is how to handle like pagination for example And I'm sure the face because they're only turn implementation of pagination But you know like most of the things you can just like do them yourself. You could just like pass some meta attributes It's not like super complicated. I think it's much more important to have a Good mental model for how you're working rather than like having all like all the small things you Most of the times you can work out the small things But if you have the big problem on the mental model that you have of your back end There's no tool which is gonna fix that and especially if you're working with a lot of other people Yeah, you're out of luck. There's no way to fix that like you have to fix the system You can't fix like the little tools Yeah, it's a it's a problem because basically it means that you can't really cash because you only have one endpoint About this I think what the Facebook guys do is to Store some basically prepare some statements, you know the good old trick of database You prepare some graphical statements and you send IDs to them and then the client just tells you okay run me the statement with ID 227 and they have the service just like Lists all the like available hot queries But yeah, like usually it's a bit of a problem because you can't cash this like in the way you cash rest calls Yeah Yeah, exactly and that's how what like relay does like if you take a look if you Take a look like how they're they built relay. It's super interesting to see The potential that they use like to the full potential which you can use GraphQL to so for example They have this really cool example where they Show a list of elements and they just fetch a very small representation with each object And then as soon as you go into the more detail It will run a query which just fetches the fields you haven't fetched yet So it's really smart and I know that for most people just say well But it doesn't really matter in the grand scheme of things because you're loading an image with just five megabytes, right? But I think it just like shows like how much potential That type of approach can have and you would never be able to do that using rest So it's not I don't think it's the matter of like how many kilobytes you can save But it's just like how much potential can you have this sort of approach and I think it's worth it Well, is this issue of like in like super nesting so You have as many is then basically the in the You have like right now in our Serializer where we transform the GraphQL payload into Amber like JSON API compliant payload You need to basically be able to distinguish like if there's duplicated data or if there's Mmm Like if there's like too many nesting and stuff like that so for right now We're like oh, we're just gonna use a sink relationships So when you're using a second relationship, obviously you don't really care about the has many that much anymore And you you don't specify all the fields you and also like when you're using has many's which are a sink false It means that you're a sink in this they should I think the other one then it should I think the other one is just like Maybe we can solve our own issue, but we can't really I mean we still haven't figured out how to write a Generalized solution to expose to the world in the add-on so and that's like the main But but the thing is like in the graph can like mental model. You shouldn't do that anyway I mean You like you shouldn't like try to be too inclusive include everything But right now just like for the simplicity and like when I when I released this ember graphical adapter And I switched one of the resources that we have in production I didn't have to change any line of client of like application code I just kept everything else the complete same and just switch the Adapter and a serializer if we want but our plan for the future obviously is to exploit this more So we want to have like more customized endpoints to have like to be able to really exploit these Graphical endpoint that we have so in the future we'll have to explore that a bit more but right now We're just like I'm just gonna touch this as like just like This is really surgical intervention to it and see how it goes and it's been working quite well And I like I like never seen like something going wrong there for now. It's really small, but Postgres so actually just like Ruby code which is fetch this from postgres anyway So the back end code is just exactly like a Ruby controller, but in a more structured way