 Everyone, this, we're now having Mihal, who is going to talk us about building beautiful RESTful APIs using Flux. Let's give her a great welcome to her. Hi, everyone. Thank you for coming to my talk. I'm going to say a few words about myself first. My name is Mihal. I write a blog, which you're welcome to visit. I do a little bit of everything. I do a little bit of Linux administration. I write code in Python and in JavaScript. I'm currently working at Intel as a tech lead for a web UI team. Before I begin the actual subject of my presentation, I want to get an overview of the room. How many of you know what REST is already? Okay. That's nearly everyone. How many of you know what Swagger is? Okay. That's fewer. All right. I'm going to give a few introductory slides for everybody who didn't raise their hands. And let's begin with the definition of what an API is. When we're building modern web applications, then they usually have a component running in the browser. If it's interactive, it's usually powered by JavaScript. We may have a client on the mobile space, so on a phone or on a tablet. Then of course we have our server with all the data and the databases. And in order to get these things to talk to one another, we need a way for them to communicate, which is the API and what is REST? For REST, it stands for Representational State Transfer, which sounds complicated, but in reality it's just a clever way to use HTTP to build APIs. So in order to talk about REST, we need to talk about HTTP, at least a little bit. So the basics are, like everybody knows, the client sends a request and the server sends back a response. But both the request and the response can be further subdivided into these parts. The method is things like get or post. They decide what will happen when the server gets the request. So get traditionally was to fetch a resource from the server. Post was used to submit data in a form. But there are quite a few other methods that can also be used. Then there's the path. Traditionally, it was a path to a file on a server. These days it's actually, in case of REST APIs, it shows us which endpoint we're going to use. Then there's also the query, which goes into the same line with the path. And there we can specify parameters. Then we have headers, which is the place through which we send cookies back and forth. And then there's the body of the request, which, in case of the REST APIs we'll be talking about, is going to contain JSON. Response is simpler slightly. It only has one field in the top row, which is the status code. That comes back with 200, if everything is okay, usually. It may come back with an error message, like 404 or 500. But there's a long list of other status codes that are defined in HTTP, and these can also be used. So REST is a convention through which we can use HTTP to access methods of our API. These are usually divided into collections, items, and a special entity called the controller. So the collection and the item endpoint, like in our example, the collection is just books. It allows us to fetch a list of books from our API by issuing a GET request to that endpoint, or to create a new book by issuing a POST request to that endpoint with information about the new book that we want to create. An item has an endpoint with an ID, so in our case, slash book slash 123, 123 identifies a specific book, and this allows us to perform operations on a particular book. So if we issue a GET request, we'll get this information about this book. If we use a PUT request, we can update the book or delete it with a DELETE request. So these are all the CRUD create, update, read, delete operations, but oftentimes we need to issue other, more specific instructions to our API, and for that we can use a controller, which can have an address, like in this particular case, book ID borrow, and this allows us to, for example, borrow a book from a library. So that's all the introduction now out of the way, and we can move on to talking about some Python libraries. The slides I'm going to be showing, the code samples I'm going to be showing you, are all based on Flask, and so Flask is a web micro framework. How many of you know Flask? Great. Okay, so Flask is a micro framework, so in itself it is not very opinionated, and it doesn't do very much for you, but it has this whole ecosystem of extensions that you can use with it, and the real hero of our story is this extension to Flask. Flask rest plus, and it handles a lot of the common tasks we have to do to define an API for us. So it validates input and gives us errors if there's anything wrong with our input. It can format our output, so we can return, from our view method, we can return something like an SQL alchemy object, and that will be automatically transformed into a JSON object according to a specification that we provide. It can even turn Python exceptions into HTTP responses, so we don't need to worry that if we raise an exception somewhere that it's going to return a 500, we can catch it and turn it into a specific error message like 404, I couldn't find what you were looking for. Then it doesn't matter where in the code the exception was actually raised, it will be intercepted by the API and turned into a machine-readable error message. And Flask rest plus is pretty cool because it allows us to use very minimal boilerplate code, but its killer feature is actually the fact that it generates swagger UI for us, so it generates interactive documentation for us. So with that we come to the part of the presentation that can go wrong, so we're going to have a little demo. It's going to be really minimal, so hopefully it won't go wrong. I have a local copy of this setup running here on my computer, so I'm just going to go to the URL of the API, and what we get is a list of all the methods that I defined in the API. So this is just a sample for some blog categories and posts, and we can look at the list of methods that we have, and we can actually use them. So we get an entry for the post method, if we provide it with a properly formatted JSON object that can create a blog post, we can click try it out, and it will actually submit the request to the API, and it will give us all the information about what happened. It gives us the response code, in my case it's 201, and there's an explanation up here, 201 means post successfully created. Okay, cool. So there's also the body of the response with an ID of the newly created post, and any other information that you would wish to provide. So then I can go to another endpoint that can fetch a particular post from the API. I saw that the ID was 10, so I'll go to try it out, and I get my newly created post back. So a very simple way to navigate your API, to learn the methods it has, can browse through the documentation, because if you put documentation in here, it will be displayed, oh, this is the part of the demo that goes wrong, I can't find any documentation. Oh, there you go. So you can actually put documentation in here that will be formatted with markdown and displayed for the user. So this is great for other developers that want to consume your API. And you get this automatically just by using Flask and REST plus. So how does this work? This works because Swagger generate, because Flask, REST plus generate a specification of your API in the open API format. This is more or less what it looks like. It's just a list of all the definitions of your methods and the inputs and outputs of these methods. And this is pretty cool, because this open API specification is a standard or is becoming a standard now. And so there's tooling that's growing around this format. Swagger UI is just one of the tools that we just saw, but there's also something called the Swagger Editor that allows us to edit this specification. And there are also code generators. So if you have Swagger documentation for your API, you can run it through a code generator and generate clients for your API in different languages. So this initiative has many powerful members. All of these companies are supporting it. It's an open source project, so I think it's going great. But now let's go to exactly how we can use Flask, REST plus to get all this done. So we'll start with the request fields. And the first one on the list is the request method. So in order to get an API using Flask, REST plus, all we need to do is define a class which inherits from something called the resource in the library. And then in that class we define functions, which match by name the different operations that HTTP provides. So we can define a get method, a post, a put, and so on. And that's it. That's all we really have to do. You'll notice the documentation I put in this method, and that automatically becomes the documentation that is displayed in the Swagger UI. And if you have a list of methods, they become this nice interactive list in the Swagger UI. And the next part is the request path in the actual URL path to the endpoint. And you define that just by adding the API root decorator to your class. And you can specify parameters which will be part of the path just by putting things in angle brackets in the path definition. So after the colon, there's the name of the parameter, and before it, you can define the type. So that will also be validated by your API. It will check if it's the right type. If it's not, it will return a 404 saying that you couldn't find that particular path. All these become part of the interactive Swagger documentation. Okay. Next is the query. And the query is composed of fields. So to get a query into your API method and check if it's valid, you use something called a request parser. So you create a request parser object, and you add fields to this, to the definition. You can specify the name of each field, the type, even additional options, like if it's required or not, or options that are valid. And all of this will get automatically validated when a request comes in. To attach your request parser to a method, you just use this API expect decorator. And then you can also use the parser in the body of your method to get the actual values of the arguments if they're valid. And this, of course, also becomes part of the interactive form in Swagger. Next thing is the body of the request that comes in. In FlaskRest Plus, to validate whether the request is properly formatted, whether the body of the request is properly formatted, uses something called an API model. So this is slightly similar to the request parser. You also add fields to a definition, but it's more flexible. And that's how a basic example looks like. You use the API expect decorator to attach it to a method. And then in the Swagger UI, you get that payload text field that comes with additional documentation on the right. You see what the expected format is. And these API models are actually quite a bit more flexible because of two things. They allow inheritance and nesting. So both of these are on this slide. You see that first I'm defining a model called category, and then a model called category with posts. Because I'm using the API inherit method, the category with posts model will inherit everything, every field from category. So automatically it will include all the fields from the model that specified at the end of the line. And it will also include these additional fields that I'm providing it in the inheritance method. And the field I'm actually extending this model with, called posts here, is a nested field which is actually a list of nested blog posts. You can see it's actually quite easy to read, a list nested blog posts. So this model will expect to get an object which contains a list of other objects. And this works very well for more complex cases. We can go on to the response, the fields of the response object. The status can be documented by just adding an API response decorator to either the resource class if it applies to every endpoint in your entire resource or to specific methods. And then that's enough to get the documentation. And at the end, you see there that to return a particular status code from the API, all we need to do is to return a second value from the method. And that's a flash convention that if it's a number, it will become the actual HTTP status code. So that's what a table of documented responses looks like. And the last, on our list, the last part of a response that I'm going to talk about is the body. And you use the same API models to format your output of your API methods. So you can actually use them both for validating input and formatting output. When you're actually outputting something from your API, you may point to a different attribute on your object than the one that you want to have in the output. So like in this example, I have category underscore ID, which is just an integer. But it comes from an object within, which is linked to my SQL Alchemy object that has a relation to my block post called category that has a field called ID. And we can actually use a whole string of fields connected by periods to show the path to get there. And if it's more complicated than that, we can use a callable to quickly calculate the value of the field that we want to output. To tell our API that we want to use this model for formatting the output, we use the Marshall with decorator, or if we are planning to return a whole list of items from our API, then we can use the Marshall list with decorator. That's all you need. That's going to automate the output. It's pretty cool, actually. Okay, so last but not least, we can tell the API to handle exceptions for us. This is how this can be done. You use the API error handler decorator on a method to specify this will be your error handler for this particular type of error. So like I mentioned before, if we use this error handler, then wherever in our code we get a no result found exception, wherever that is raised, that will be caught before the API returns. And in this case, we'll log a warning and then return a 404 message. If we don't catch an error and we're running in debug mode locally, then we get something that's also pretty cool, an interactive debugger which runs in the browser, and this is part of Flask. Actually, I think it comes from work. Anyway, you get this interactive debugger which runs in your browser, and you can type Python code in here and see what's going on without ever leaving the browser if you want to. So this was my rundown of all the features that Flask, REST, Flask provides. So now how much would you pay? All you need is ten lines of code to get started with this. This is like a minimal hello world API that will come with all the features that I described. There's a more complete code demo and an article about all this on my blog. So if you go there, you can download the demo I showed you and read a little bit more about the things I said. Thank you. We have time for questions first. Hi. Thanks for the talk. Do you have any feedback about EVE? It's another Flask library for REST APIs. And you know, if you can use some way of discovering in the REST plus to avoid writing the IDs, the fields of the model two times, one in the validator and one in the SQL alchemy model. Okay. Well, so I guess those are two questions. We've tried using EVE, and it's actually very cool because it automatically generates the whole API, RESTful API for you based on your model definitions. But we in the end decided that we don't want to expose our database as is through our API. We actually need custom end points. So that's why we didn't end up using that. And no, I don't have any way to create an API from SQL alchemy definitions. But it should be straightforward thing to do. So I guess it could be attempted, but I haven't found something that does it yet. Hi. Thanks. You said that an API can be generated from the open API definition file. Can that be done with or for Flask REST plus? Not yet. So the code generator, which is part of the open API initiative comes with, it's essentially a set of templates for different languages. There is one for Flask, but it uses a different library, not Flask REST plus. So I was actually thinking of doing that, generating a set of templates for this code generator, but I couldn't find the time to do it myself yet. So maybe somebody will do it, and then it will be possible to do it. Hi. Thanks for a very good presentation. I was just wondering about your experiences with the workflow or the direction of the workflow, because if I understand correctly, the authority of the structure is the Flask application due to by virtue of its decorators, and that generates then the API. In our experience, we usually have a different direction, like we design the API together with the front-end developers and product owners, and that becomes sort of the authority, the canonical, so the YAML from Swagger API is the canonical definition of what we need to do, and so then we write the backend to conform to that, and the front-end people then obviously write their clients to that, so that has the reverse direction. How is your experience with what you've described? Well, the truth is I don't have experience doing it that way. I wish I did. It sounds like the right way to do it, but in our case, we were creating the API by writing code, and then the specification came out of that instead of the other way around. But then I have a question for you. So what happens when you change the definition? Do you regenerate the code? Well, we don't generate any code. We craft it levelingly by hand. That is sort of our selling point. No, but in seriousness, when it does change, then it first changes the YAML, and then we discuss whether that makes sense, and then maybe we start coding. So in practice, it's actually no, I don't care if I have to rewrite something then because now there's a good reason. Okay, but then you have to keep them in sync, right? Yeah, I find that's a lesser of two evils. Okay, very nice. One last two questions. Hey, thank you for your talk. Can we ask REST Plus to provide anything for hyperlinking to related resources at all? No doubt of the box that we had to implement our own logic to do that. That's all our time. We'll chat later. Thanks to the speaker again.