Tuesday, October 04, 2016

Michał Karzyński - Building beautiful RESTful APIs using Flask

everyone and this in this with now having me help
who's going to talk to us about the building beautiful restful api is using
flex this give a great welcome to hear
hi everyone thank you for coming to my talk and I'm going to say a few words
about myself first my name is me how I write a blog which you are welcome to
visit and I do a little bit of everything i do a little bit of linux
administration i write code in Python and JavaScript and i'm currently working
at Intel as a tech lead for a web UI team
so before i begin at the actual subject of it of my presentation I want to get
an overview of Durham
how many of you know what rest is already ok that's nearly everyone
how many of you know what swagger is ok 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 and modern web
applications then they usually have a component running in the browser if its
interactive it's usually powered by JavaScript we may have a client on the
mobile space so on the phone or on a tablet and then first we have our server
with all the data and the data bases 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 them
for rest stands for representational State transfer which sounds complicated
but in reality it's just a clever way to use HTTP to build a p is so in order to
talk about rest
we need to talk about HTTP at least a little bit so
the basics are everybody knows that client sends a request to the server
sends back a response but both the request and the response can be further
subdivided into these part
the method is things like get or post they decide what will happen when the
server gets the request to get traditionally was to fetch a resource
from the from the server post was used to submit data it in a form that they're
quite a few other methods that can also be used then there's the path
traditionally it was a path to a file on the server
these days that's actually a in in case of restful api is it shows us which end
. we're going to use and there 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 we went through which we send cookies back and
forth and then there's the body of the request which in case of the RESTful API
will be talking about is going to contain Jason responses simpler slightly
only has one field in the top row which is the status code that comes back with
200 if everything is ok usually and may come back with an error message like for
a four or five hundred but there's a long list of other status coast at the
status codes that are defined an HTTP and these can also be used so rest is a
convention which we can through which we can use HTTP to access methods of our
API
these are usually divided into collections items and special entity
called the controller so the collection and the item and . like in our example
for the collection is just booked
it allows us to and fetch a list of books from our API issuing a get request
to that end . or to create a new book by showing a post request to that end .
with information about the new book that we want to create an item and has an end
. with an ID so in our case / book / 12 38 that I went to three identifies the
specific book and this allows us to perform operations on a particular book
so if we issue a get request will get this information about this book if we
use a foot request we can update the book or deleted with a delete request
so these are all the crud create update read the 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 the
library
so that's all the introduction now out of the way and we can move on to talking
about some some Python libraries the slides i'm going to be showing the code
samples i'm going to be showing you and are all based on flask and so flask is a
web micro framework how many of you know flask
great okay so-so flask is the is the Micro 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 flash class chris plus + and it handles a lot
of the common and common tasks we have to do to define an API for us
so and it validates and put and gives us errors if there's anything wrong with
our input it can format our output so we can return for from our view method we
can return something like an SQL alchemy object and that will be automatically
tech transformed into a Jason an object according to 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 to 500 we can catch it and turn it into every a specific error message
like 40 for I couldn't find what you are looking for and 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 and error message and last
press press press is pretty cool because it allows us to use very minimal
boilerplate code but it's kind of a killer feature is actually the fact that
it generates swagger you I for us
so did generates interactive documentation for us
so with that we come to the part of the presentation that can go wrong
so
going up we're going to have a little demo it's going to be really minimal
so no please walk around I have a local copy of the sort of this set up 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 and and in the API so this is
just a sample for some some blog categories and posts and and we can look
at the list of methods that we have anything we can actually use them so we
get an entry for the post method we if we provided with a properly formatted
Jason 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
gives us the response code in my case it's 21 and there's an explanation of
here to one means post successfully created
ok cool so there's also the the body of the response with an ID of the newly
created post and any other information that you would wish to provide then I
can go to an end to another end . that can fetch a particular and ID particular
post from the API
I saw that the idea was 10 so i'll go to try it out and I get my newly created
postback so very simple way to navigate your API to learn the methods that has
can browse through the documentation because and if you put documentation in
here it will be
display know this is the part of the demo that goes wrong I can't find any
documentation
there you go so you can actually put the documentation here that will be
formatted with mark down and displayed for the user so this is great for other
developers that want to consume your API and and you get this automatically just
by using a flask in first class chris plus
so how does this work this this works because swagger generate that because
class chris plus generate and and a specification of your API in the open
API format
this is more or less what it looks like it's just the 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 this format
swagger you is just one of the tools that we just saw but there's also
something called swagger editor that allows us to edit the 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 is this initiative has many powerful members all of these companies
are supporting it
it's an open source project so i think it's it's going great but now let's go
to the - exactly how we can use flash press + 2 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 flash first plus all we need to do is define a
class which inherits from
something called called the resource and in the library and then in that function
in that class we defined functions which match by name
the different operations that HTTP provide so we can define a get method
opposed to put and so on and and that's it that's all we really have to do and
you'll notice that documentation i put in this method and that automatically
becomes the documentation that is displayed in the swagger you I and if
you have a list of method method they become this nice interactive list and in
the swagger you I and and work ok so the next part is the request path in the
actual URL path to the end . and you defined that just by adding and and the
API route decorator to your class and you can specify parameters which will be
part of the past just by putting things in angle brackets in the in the past
definition so after the colon
theirs is the name of the parameter even before it you can define the type so
that will also be and validated by your API it will check if it's if it's the
right type of its not it will return the 404 saying that you couldn't find that
particular path all these become part of the interactive and swagger
documentation
ok next is the hurry and the query is the composed of fields
so to get and a query into your API method and then check if it's valid use
something called a request parser
so you create a request parser object and you add field to this
- - the definition you can specify the name of each field the type even
additional options like like if it's required or not or options that user
that that are valid and all of this will get automatically validated when a
request comes in to attach them to attach your request parser
- I method you just use this API expect decorator and then you can also use the
the parser when the body of your method to get the actual values of the of the
arguments if they're valid and this of course also becomes part of the
interactive form
Austin swagger
next thing is the body of the request that comes in and flash first bus to
validate whether the request is properly formatted whether the body of the crest
is properly formatted uses something called an API model
so this is slightly similar to the requests are so you also add fields to a
definition and but it's more it's more flexible and that's how basic example
looks like you'll use the API expect decorator to attach it and to a method
and then in the swagger you I you get that payload text field that comes with
additional documentation and 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 there's the hell out inheritance and nesting
so both of these are on this slide you see that first time 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
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 post here is a
nested field which is actually a list of nested blog posts because it's actually
quite a t32 list next blog post so this model will expect to get and an object
which contains a list of other objects and the this works very well for more
complex cases and we can go on to the response
yeah fields of the response object the status can be documented and by just
adding an API response decorator to either the resource class if it's for if
it applies to every endpoint and in your entire resource or the specific methods
and and then that's enough to get the documentation and at the end you see
there that wanted to return a particular and status code from the API
all we need to do is to return a second and second value from the method and
that's a flask invention 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 the part of a response that i'm going to talk about is the body
and use the same API model to format your output of your
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 on your object then 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 and an object within
which is linked to my cell
sqlalchemy object that is that has a relation to my blog post of category
that has a field called ID and we can actually use a hole and a string of
fields connected by periods through to show the path to get there and if it's
more complicated than that we can always use a callable to quickly calculate the
value of them and off the field that we want to output to didn't tell our API
that we want to use this model for formatting the output we use the marshal
with decorator
or if we are planning to return a whole list of items from our from our API then
we can use the marshal list with the decorator and that's all you need that's
going to automate the output
it's pretty collection ok so last but not least
and we can tell the API to handle exceptions for us
this is how 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 there
so like I mentioned before if we if we use this error handler then wherever in
our code we get a no results found exception wherever that is raised that
will be caught and before the the API returns and in this case will log a
warning and then return the 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
and interactive debugger which runs in the browser and this is part of flat
this is not part of last course but you see if I think it comes from work like
anyway this you get this you get this interactive debugger which runs in your
browser and you can type code Python code in here and see what's what's going
on without ever leaving
well ever leaving the browser if you want to so this was my rundown of all
the features that flask rest less provide so now how much would you pay
because all you need is 10 lines of code to get started with this
this is like a minimal hello world
api that will come with all the features that that i described
there's a more complete and the code demo and an article about all this on my
blog so if you if you go there you you can download the demo i showed you and
read a little bit more about what the things I said thank you
we had we have time for questions first
- thanks for the dog and you have any feedback about Evie's another flask
library for for us baby is and you know if you can use some way of discovering
into in the rest of the class to avoid writing the ids the fields of the model
2 times 1 in the validator and once in the SQ alchemy more than ok button
well then so i guess those are two questions
II and we tried using Eve and it's actually very cool because it
automatically generates the whole API restful api for you based on your and
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 we actually need custom and . so
that's why we didn't end up using that and no i don't have any way to create an
API from sqlalchemy 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 alright thanks
you said that I an API can be generated from the open API definition file can
can that be done with 44 flask rest plus not yet
and so the code generator and which is a part of the and open API initiative
comes with and it's essentially a set of templates for different languages and
there is one for flask but it uses a different different library not flash
press + so I was actually thinking of doing that generating a set of templates
for 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 I thanks
for a very good presentation
I was just wondering about your experiences with the work floor the
direction of the work for 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 designed designed the API together with the front end
developers and product owners and that becomes sort of the authority the
canonical that
so the animal from swagger API is the canonical definition of what we need to
do and so then we write the back end to conform to that and front-end people
then obviously right their clients to that so that has I could reverse
direction
how is your experience with with with what you've described
well die 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 and creating the
API by writing code and then the specification came out of that instead
of the other way around
and but then I have a question for you so what happens when you change the
definition of you regenerate the decoder we don't generate any code we you know
we crafted lovingly by hand that is our in a sort of our selling point
nobody in Syria sins when we when it does change then it which first change
the ammo and then we discuss whether that makes sense
and then maybe we start coding so in practice it's it's actually no i don't
care if I have to rewrite something them because there's now and now there's a
good reason
ok yeah but you then you have to keep them and think right yeah I i find it
starts this lesser of two evils
ok right now and one of us to question your past
hey thank you for your talk and does france-presse plus provide anything for
hyper linking to related resources at two
not out of the box that that we have had to implement our own logic to do that
the soul of time with each other later
thanks that speaker again

No comments:

Post a Comment