 Good morning. So nice little crowd, thank you for being here. I like to start this talk with a short story of why I'm here today in front of you on a Sunday morning. And this story started a few months ago when I met a customer who wanted to replace their Salesforce system by Odoo. And Odoo for those who don't know is an open source Python ERP. And the particularity of that project was that, sorry, the particularity of that project is that Salesforce, that customer is kind of the middle piece of a puzzle and it's surrounded by a variety of in-house build application all querying and updated the central system. And since we were replacing the middle piece we had to provide API to those existing systems. And at that time we had kind of two possibilities to provide those API. The first one would have been to say, okay, just use the standard Odoo XML RPC API. And that one is useful. It's very powerful because it exposes all the Odoo object model and field. But it's actually too powerful because, well, first it's the whole thing. You need to know all the details of Odoo to use it efficiently. And then it really exposes the guts of the system. So any time you are braiding Odoo, we are adding classes, removing fields and so on. So you risk breaking your client. So that was not a good solution. And the other possibility was to create a custom REST API. That would have been clean and nice. We could document it with swagger and so on. But still I had the feeling that it was too difficult to do in the short time frame of the project. So I was looking for something more efficient. And at that time Kenneth Rice, the guy who wrote a request, was creating a small framework called Responder. And that framework is just a little thing. It's a mashup of existing Python libraries like Starlet and stuff like that. But he was including a way to create a GraphQL endpoint in a few lines of codes. And that triggered me to have a second look at GraphQL. And I quickly found out it could be a solution for a problem. And so we started. We decided to use it for that project. And it quickly was a success because my colleague who was writing the endpoint was actually quite happy and very productive at it. And our client developer were also very happy. They were all saying, oh, well, that's technology is very easy to use. And they were using PHP.net as client programming languages. And they were all very happy with it. And so, well, since it was such a game changer for us, I wanted to share that story. So here I am. So let's go. I'm Stefan. I'm the city of Akson. We are a software engineering company in Belgium focusing on a quality open source project. And I spent quite a lot of free time caring about the Odu Community Association, which is a nonprofit trying to foster a vibrant open source community around Odu. We managed kind of 200 GitHub repos with thousands of high quality Odu add-ons. And I'm doing Python since version 1.4. So today I'd like to, well, it's mostly a tutorial. I'll quickly explain what GraphQL is and go into a demo first from the client side perspective to explain or to give you a feeling of what GraphQL is from the point of view of the client developer. And then give you an example of how you can easily create a GraphQL endpoint in Python. And I use Odu as an example back end system. Then I'll discuss a little bit how GraphQL is different from other similar technologies and give you some attention points maybe you'll want to keep in mind when creating your own end points. So what is GraphQL? Well, I like to think of it as yet another remote procedure called Mechanism. In a way, it's just that. It's a way to request a remote computer to do something for you and return a response. It comes from Facebook and they open sourced it in 2015. And obviously those guys know what a graph is. But really for most usual use cases, you don't need to worry too much about the graph aspect and you'll see why in a moment. So the basic characteristics, the request and the queries you express them in using the GraphQL query language. It's kind of JSON, but it's not. So it's a specific format. The responses are pure JSON. So that's important for ease of integration. So nothing special there. There is a schema language to express, to define the various types and available queries. You don't need to worry too much about the schema language because you usually don't see it because you generated from your programming language. And then the transports, usually it's DPS. You do get and post to send and receive the data. And there is a variety of server-side libraries in most languages. And on the client side, in my opinion, it's so easy that you don't need to bother with any kind of library to use it. That's an important point. So for the sake of demonstration, we'll use a simple schema. We'll expose Odu partners, which are basically companies and contacts with their name, address, email phone, a flag saying if it's a company or a simple contact. In the address block, you have a country field which point to country type, which has a code and name. And then the companies have contacts and contacts with a partner company. So it's a simple data model. But yeah, an interesting one for a demo. So the demo, I start from the client side. And the good thing with GraphQL is that you get for free, as soon as you have a GraphQL endpoint, you get for free a web-based ID that you can use to create your request. So on the left, you have the query editor. And on the right, the result pane. And very important, you have a documentation explorer. So you can interactively explore the schema. And that documentation is automatically generated by introspecting the schema provided by the endpoint. So you see here on the right, you have queries and mutations. Mutations are for anything that has side effects. And queries is just for fetching data. If I click on query, I see the available queries. And I focus on just one of them, which is called all partners. Can use it to fetch all partners from the database. If I click on it, I see that all partners ask three arguments. The first one is a Boolean, saying I just want companies or all of them. And then limit and offset in my examples are for doing paging at the database query level. And then the return type is a list of partners. And if I click on partners, I get the field we have seen before. So simple list of field in this case. Some are mandatory. You see them with the exclamation point. And then you have country, which is of type country. And contacts, which is in itself a list of partners. So we have a recursive data structure. Now, if I start typing a query on the left, you see we have code completion. So you type control space, you see the available keywords. So I can type all partners. All partners, again, I see the list of available field. I can select those I want. And that's, yeah, I zoom a little bit. So that's a very, very important point about GraphQL is that it's the clients who decide which field they want to receive. Whereas if you are doing rest, you cannot decide. It's a server that's always giving you the same list of data. In this case, I don't want all the fields. I want three of them. And in the result, it's just a JSON list of dictionaries. And you see that it's also the second very important point. You see that the response is mirroring the query. So in the query, I say I want all partners. I get all partners in the response. I want name. I get name. I want email. I get email and so on. So your response is always mirror what you put in your query. And that's very important. Then I can use arguments in my query. So for instance, I have all partners, companies and contacts that I want to say I want only companies. That's the syntax to do that. Companies only is true. I get a limited list. And then also very important aspect of GraphQL, you can navigate in the data model from your query. So in your query, no, I want to get the contacts to. I have contacts named phone. And again, you see that the response is mirroring your query. So I added contacts. I get contacts. I added name. I get name, phone, phone, et cetera. And so that's the other very, very important aspect of GraphQL is that the client can navigate into the data model. Whereas with traditional REST or RPC, it's more fixed. So the server might have provided a service that's providing companies and another service to get contacts with, as an argument, the company ID, for instance. But then that's more server around trips. Conversely, the server could have decided to provide just one service, providing companies and contact at the same time. But then all the time you send all the data and maybe your clients don't need it. So that's very important GraphQL is that the client has the flexibility to express what data he wants to retrieve from the server. And the last point I want to illustrate is the concept of query variables. Query variables are kind of place orders you can put in your query. They can go anywhere in the query. So kind of a very complex query, but you can put place order a bit everywhere. And then it's the client which sends to the server the query plus a simple JSON dictionary with the replacement variable. And the replacement is on the server side, so there is no risk of query injections and stuff like that. But it's also very important because in terms of data binding on the client, if you imagine you're writing a web application, you need to bind the form fields to the query field. Using this mechanism, this binding is just populating a JSON dictionary. So for clients and developers it's also very, very easy because they can write their query in the IDE, copy paste it in the code in a constant, and then bind their form variables to a simple JSON dictionary and send them both to the server. Very easy for the client developers. And you get code completion also when creating variables. And so it's an example, two simple variables limit and offset for doing batching inside a large result set. Okay, so that's it for the client demo. Now we'll dig a little bit on the server side and I illustrate what it takes to create the endpoint I just used in the client side demo. And the code I was going to show is really all there is to it. I give you the pointer after that you will see that there is really nothing else that I'm going to show to create that endpoint. So the first thing to do is create the types. So I start from the bottom. The country type is an easy one. So you represent your GraphQL type with Python classes, define the country class, just a graphene object type. By the way, graphene is a very good library, an open source library to do GraphQL endpoint in Python. Very, very efficient and all this actually is made possible by those guys. So country class to just say it's a graphene object type and the fields are just class attributes. And again, you give them their type, you can see if they are required, you can provide default values, you can provide documentation, very important with comments or help attributes, for instance. And you see there is no code to do the binding to the underlying object. And why is that? Because in this case, I will have a nodu object, which has a different name. Also have a code in the field. And in that simple case, the binding is automatic because the default resolution mechanism for graphene is to do a get attribute on the underlying object. And so if your underlying object has the same attribute names, the mapping will be automatic. So for the partner object, same principle, I enumerate the fields, give their type, some are required, some not. This one is a Boolean, required two, you have access to a variety of scalar fields like ints, floats, dates and so on. Here I'm using the odu object type, but it's really a very, very small extension of the graphene object type to cope with some odu peculiarities, for instance. Odu is representing strings as null strings with false, and converting false to GraphQL does not work for, it's not represented as null, so there is small conversion there. But otherwise, for instance, for this one, it's just a graphene object type, so there is nothing specific to odu here. And then next example, the country field. The country is of type country, so that's the way you declare it. But in odu, there is no country attribute on the partner. In odu, it's named country ID. That's a convention. And in this case, what you need to do, you need to provide the mapping yourself. And in GraphQL, those mappers are called resolver. And the way to do it is to just create by convention a method named resolve underscore the field name, so resolve underscore country. And that method is taking two arguments. The root is the associated underlying object. And info is a way to pass context, like the database connection, the current users or stuff like that. So in this case, I map the GraphQL country field to the odu field name country ID. And country ID is not an ID in odu, it's actually a country object. And that will be bound to the GraphQL country type. And then GraphQL will resolve the country attribute code and name and then continue like that. Same for context, context is a list, a list of what a list of partner, the list is required. In odu, I don't have a context field, I have a child ID field. And in this case, resolve context will return, just return root dot child IDs, which means I'm returning the contacts. Child IDs is a list of odu partner object that again will be bound to the partner GraphQL type. And again, Graphine will recursively call the resolution mechanism that you start to understand to recursively resolve all the fields. And that's all you have to do to map those types. And then you have the top level query. So we come to all partners that we've seen at the beginning. All partners is returning a list of what a list of partners. And then it has three arguments. You see again, companies only is a Boolean limit and offset that we have seen before. And that as is does not exist on the backend system, so I need to write a resolver too. It's always the same, write a resolver. So I write resolve all partner, I get root and info again, and then the arguments, companies only limit offset. And then that's more traditional stuff. I build my query. So that's a little bit of odu code. If the client wants companies only, I build my query, his company is true. I do an odu search and I pass limit and offset. And the odu search is going to return a list of partner objects again that will go to the resolver mechanism and so on. And then a few small glue code to create the HTTP road. And basically that's it. So that's all you have to do to bind a GraphQL schema to an existing backend system. So as you see, there is very little odu code so you can imagine that's going to work with basically anything you have. If you have Django or SQL alchemy in the backend or whatever you can think of, it will be as easy to do it. So very efficient. Okay, so now let's discuss a little bit of GraphQL. Let's go a little bit deeper. So how is GraphQL different? Well, I like to compare it to two things. On the one side, traditional RPC technologies and on the other side, SQL. Traditional RPC technologies, those are very different, Decom, Corba, SOAP, REST, whatever. But in the end, they have in common that you have a rigid request response structure. So the service you provide define exactly what the client can request and what he will receive in response for any service. They all have some sort of schema language that is machine-reasonable so you can introspect it, implement validation, and the standard on-the-wire protocol. And for those is the service developer who implements all the server reacts to a service. And on the other end of the spectrum, you have SQL. And there, of course, you have a database and then it's a client that has the full freedom to express his query. He can do whatever he want provided it follows the database schema. So full flexibility for the client, but so to speak, there is no server-side developer. You must have a database. Okay. If you exclude store procedure which actually fall in the other category, you have no possibility to or it's very difficult to access external systems within a SQL database. So GraphQL is a bit in between. So you have full flexibility for the client to express the query. But on the other side, you have a very easy mechanism for the server-side developer to decide how to respond to any given query. And so you don't even need a database. You can query back-end systems or a variety of whatever you want on the back-end. So it's really something in between RPC and database query language. So some attention points. While you sometimes read on the internet that GraphQL is presented as a better rest. So is it, is it not? I don't know. It's different. But first of all, the typical complaints you see again, GraphQL is people say it's not respecting HTTP semantics. Well, that's true. And GraphQL basically use HTTP as a dump pipe to send a request and get the responses. So you don't really benefit from the HTTP infrastructure for caching and so on. You benefit from authentication and stuff like that. But some HTTP infrastructure is oblivious to GraphQL. Well, to me, actually writing a good REST API is incredibly hard. It's really an art that very few masters are doing your REST API that respect HTTP semantics fully. So, yeah, you decide for yourself. For me, it's a better rest in the sense that it's, you are really more productive when creating services with GraphQL than with REST. That's something that I see for real and real projects. Another attention point is performance. You must pay attention to the way you write your resolvers. For instance, in the resolve contact one, if I would have written for each one, doing a search on parent ID is root ID. That would have worked too. But in the end, that would have generated one database query for each parent company in the result set. Not very efficient. So the good thing to do is to exploit the power of your object relation and mapper. How does it, SQL alchemy does it, they have prefetching strategies. And that would end up in this case in two queries, one for the parent, one for the children. And so much more efficient. So need to pay attention to that. The other aspect is decide what to expose in your GraphQL endpoint. With some tools, for instance, there are adapters for Django, SQL alchemy. It can be very easy to expose your whole object model at once without doing almost anything. It can be useful in some cases, but I advise to create GraphQL endpoint that are specific to the client use case. Because exposing your whole object model will prevent you changing it because you will never know what parts of it are used by the client. And since it's so easy to create specific schemas, you really need to use that power to do schemas adapted to the client use case. Okay, finishing. Access control, pay attention to it. Because for rest it's easy to put access control at the entry point. Here you need to put access control at the level of the domain model. So key takeaways. It's different. I really encourage you to try it. If you see it as another way to do rest, you will see that it's a very powerful technology. And in my opinion, you get really more productive than by doing rest. You give a lot of flexibility to your client developer and a lot of productivity to your server-side developer. You have the links, the slides are online. And I don't know if you have time for questions. No time for questions. So I'll be around. Sorry.