RESTful API - Best Practices.
Nowakowska, Malwina
Malwina Nowakowska - RESTful API - Best Practices. It is important to understand from the beginning how model API should look like. Do not repeat your friends’ mistakes and make developers upset! There are some simple rules that can make your API cooler - clean, safe and efficient. Based on both bad and good examples of REST APIs (I had to deal with) we will learn about best practices. - Nowadays building and integrating with Representational State Transfer web services is a very common thing. It seems that creating RESTful API is trivial - nothing could be more wrong. In my previous projects I had to integrate with lots of APIs. Unfortunately only some of them were easy to work with. Most of the APIs did not follow the main rules of model API. It is really important to understand how model REST API should look like. To make developers happy we will learn best practices of creating REST API from the beginning. We will start with quick introduction what REST is, why principle of REST is so amazing, talk about identifires and explain some key terms. We will discuss about architectall constraints and properties. Mistakes and best practices are based on my experience of developing and maintaining the projects. After this talk you will be able to create model RESTful API developers will be happy to work with.
 The next talk will be a restful SPI best practices by Malvina. Let's give her a big applause. Welcome everybody. I'm Malvina. I'm a developer at STXnext, the biggest Python software house in Europe. Almost five years ago, I brought my first line of code and that's how my Python journey began. When I'm not hacking, I'm trying to spange time actively at the gym or in the nature. Okay, so let's begin with a short story. Some time ago, in one of my previous projects, I had to make many integrations with many providers. And each of them had very different level of APIs. We are working on module which was offering tickets for many kinds of events from many suppliers. At the beginning, we started implementing integration with the main provider. Our first task was to implement a simple search. The endpoint for searching was limited. The API provider offered us only searching but the date or text. So after consultation of our product owner, we decided to develop the same functionality. While working on it, we started to see first little, started to get to know better the API and started to see first minor issues. The first surprise was fact that they didn't have paginations. So in result, we had to store all data on client side. Other fact, the documentation was so poor besides the fact that it was really hard to find any information. This information was incomplete. For example, there was no info about return object types, which started to make sense after noticing that the return object types are not consistent. Some feeds could start on an empty array or there was a feed that store a data time object or a regular event and string with date range for festives. From our PO point of view, the satisfying was fact that we didn't display prices on the list view. This information wasn't returned by endpoint for searching and calling the other endpoint for all return events would be too expensive. So after first branch, we developed something like this. To cheer up our PO and improve user experience, our next task was enlarging searching. We wanted to add filtering and sorting the events. The API provider wasn't offered as such complicated features, so to achieve this goal, we decided to store all data and we wanted to make sure that we could download our database. We developed the Chrome jobs that were downloaded events every day at midnight. Additional advantage of this approach was fact that we could also download the prices by calling other ad points. Every frame seems to go well, but it was a calm before the storm. The problem appeared when all developers and testers started using in on their own local instances. It was edge people. The API provider wasn't prepared for so many codes, so they didn't catch the queries and in result, they banned our IP addresses. After this action, this banned us another couple of times. Another visible dropback was fact that they didn't have the best environment. The outcome of this was a small disaster. First of all, there was so many fact data on production, like special demo events specially prepared for testing buying the tickets. You have to spend a lot of time on their side to find it, whereas on our result page, this data was more exposed. Also, to prevent buying real tickets, our API key was locked, but when we wanted to release our feature, we needed to test buying real tickets. So, API provider delivered us other unlock API key. Unfortunately, some misunderstanding occurred and they unlocked rank API key. We find it out when a postman came to our office one beautiful day and delivered us a ticket. During integration with another provider, the most surprising were your N names. They were very un-intuitive. To get the events, you have to go to slash localization endpoints and event endpoints was performances and sorry, I just lost myself again in the manner of mention of it. Also, data structure was so messy. This API was developed without understanding the client's need. We spent a lot of hours to get the logic and map the structure of events to ours. So, the question is what could the API provider have done better? One of the answers can be restful and it's not a problem. Rest stands for representation of the answer. It's an architectural style with a set of constraints that allows a simple communication between two systems, typically a client and the server, where communication between these is based on HTTP. And now is the question for you guys, who is the most important part of the project? I thought so. The form describes six architectural constraints. Clean server architecture style is the basic restriction for restful application. The system is disconnected. For example, clients are not concerned with data storage and the servers are not concerned with user interface or user interface. The question is to separate architecture and responsibilities in both environments. In Wizard, we improved the portability of the client's code by simplifying the server's components. Stateless is the constraint to the client's server interactions. One client can send multiple requests to the server and each of them must be independent. This means that the client's request to the server must contain only that information to service the request. In order to improve network efficiency, rechart data from server are explicitly labeled as cacheable or noncacheable. We can cache response messages on client on the server or above side. The rule to create a cache can be different for each user. The user can use the cache after a given period of time or whenever there is a change in some state. Uniform interface is a central feature that distinguishes restful architecture style from other network-based styles. It's a well-defined contract for communication between client and the server. The four guiding principles of uniform interface are the first one is to identify and get resources, manipulate and get resources through representations, send descriptive messages, and hypermedia as the engine of application state. The layer system style allows an architecture to be composed of hierarchical layers. There can be multiple layers of software involved and retrieving information. So server may improve or increase the network소� stray. It takes solutions from employer to provide the way, balancer, firewall, or by providing short caches. Codes on demand is entirely constrained. The server can have the functionality of clients by transfer of executable code. Codes on demand are always applets, or client-side scripting languages. Complaining with these constraints, REST introduced certain architectural properties. Web service APIs that add here to the REST architectural constraints are called RESTful APIs. Many people would go on to say that RESTful API uses only HTTP adjacent. And all of this is important, and it's part of RESTful itself. But to consider an API RESTful, it must truly follow all the rules defined in REST architecture. It's worth to be familiarized with learn how to try its own REST maturity model. A maturity model is a MIPE that guides users into level-increasing levels of compilance with some definition, methodology, or architecture. The REST maturity model is the same time of improvement map for building web services. This maturity model knows four levels where the last one designates a truly RESTful API. The concept of REST is to separate the API structure into logical resources. Individual resources are identified by your REST. During design, the API resources don't directly map one to one your database into resources. You don't want to irrelevant implementation details in your API. Use sensible resource names. For example, in our ticketing module, some of the resources could look like this. You should notice that all of these resources are now not verbs. Also, don't mix up singular and plural nouns. Keep it simple and use only plural. Use one case convention. There are three main case conventions, common case, next case, and spinal case. As a Python, it would probably pick the snake case. Also, avoid apostrophes, spacing, and other exotic characters. Resources are identified by your REST and manipulated by HTTP operations. Post-get push-patch delete corresponds to create-read-update and delete. So remember, get method should not alter the state. To sum up, if you want to retrieve a list of events, use method get or resource event. To get a specific event, just add ID to this resource. And if you want to create the event use pod method on resource events, to update some event use put or patch method on the resource of concrete event, and to delete use method delete. If you have a relations, good practice is to use super sources, but make at most two levels of nested API object. Operations under resources look the same. Also, you can consider add to your response related resource representations. By default, use only this almost access together. Avoid accumulating too much information, and don't embed collections if it has too many components. By just approach, you then can avoid making extra API calls and improve efficiency. And if that feature would be in our API, in my previous project, you would have had prices on the list view from the beginning, and our API would be happy. To describe return values, our API should return relevant HTTP status codes. Of course, we should use this one now. For example, 200 other cases can be used to a successful get. When we create a successfully API, should successfully a resource, API should return 201 created. In this case, we should add to our response related URL to the just created resource. To handle the errors, also we should use HTTP status codes, like here in an example. Also, to inform user what happened, put show a useful error message. For large data sets, limit the return amount of data as important. Try to make advance searching just add query parameters to the URL. If you want to enable fortralling, just use attribute name with an equals sign and expected values. The sort results use parameter sort or ordered by with the name of attributes on which sorting will be performed. This will understand the just add hyphen before the attribute name. Sometimes basic filtering does not fit our needs. Then we should consider providing full text search, calling by multiple fields. A nice approach is to enable to think which are in response. Clients can save valuable memory by retrieving only needed information. There's parent fields that takes a comma separated fields to include. According to the rest theory, actions or resources are constrained to create read update delete. But in real life, there are some cases that doesn't fit those rules. For example, if you want to implement a multi-resource search, compute or convert something. For these exceptions, you should use verbs as URL names rather than an ounce. We should use URL names that are the most fitting. But also carefully describe these exceptions in your documentation. It's hard to foresee all resources presentation. Almost each evolve after time. It's natural to version your API. There are many best approaches for versioning APIs. The most famous is to include version. And URL path. But other piece of work is it by adding version in HTTP header. Oh, and don't advance default versioning. Paginate the results to make response easier to handle. Even if at the beginning you don't have large amount of data, you don't know how it will be in the future. And do this in an early design phrase is easier. So there's also no one paging mechanism. You can add paging to your request by URL or HTTP header. In response, you can return pagination and envelope or header. For example, rate or length header. As the result, we can easily navigate it through the pages and consume the results. Both client and server needs to know which format is used for communications. We can use HTTP headers dedicated for this. In content type, define the request format and accept specified return format. In response messages, enable pre-preprint. It will be easier to debug or analyzing your API through the browser. Try evolving your response messages. In most cases, an unnecessary extra layer in the response messages. HyperMedia is the engine of application state. It's the most omitted constraint. But you should try to use it in your API. Just provide links to your API. If you don't have links in your API, your API is still be useful. But after providing them, it's more discoverable and self-descriptive. For example, if you want to find Madonna concert in some events portal, you have to go to search page, type Madonna, and pick proper event. To do this by your API, first you have to go to documentation and find endpoint for searching. And then you have to do the same to find out how you can display a proper event. And after providing the links, all you need to know to find Madonna concert by API is your root address. You can interact with API just like you interact with browser. Documentation is an important thing. Documentation is an important part of API. It should enhance in commerce and make life easier for current users. So describe all features needed in formations. Put the examples of usage or request or responses. Use code for this and your API will be easier to debug. Documentation should be easy to find and user friendly. Try not to use developer jargon and make it pretty. From my experience point of view, I have this strange feeling that many developers are in kind of student state of mind. I mean they're not business nor user focus. They forgot they developed feature for real users, which is totally opposite to 100% back free demo path, especially created to satisfy professor need and pass some classes. And there is a high chance that it will fail each other way. And I'm sure you know what I'm talking about because we all did this. So remember, have a doubts. Make sure your code follow the best practices. Even the slices. Investigate how some part of your API should look like. Check how web giants do this. Use Google search to solve problem or use this issue to initiate the small talk in the kitchen or put this subject in your team. Use best practices where they make sense. But of course, don't get stuck in an infinitive loop of researching best approaches. Think, comment, and go. The most important part is fact that you are thinking about the user. Thank you. Thank you. We have time for questions. I've got a question. When you talk about links in your API, did you use or is specified anywhere the names? The examples of links? The example of links. For example, the metadata or? Yes, you should use your name names and the method. And you can also provide a short description about what this link is. Thanks. Good questions. So you mentioned indeed about putting links in the response. And I guess that's what you indeed do as best practice. Do you have any recommendation of how nested your response can be? I'm sorry. Can you say something louder? Yeah, you can hear me now. Yes, better. OK, so I was wondering how nested can response be? So how many layers of nesting you can do? By providing links, yes. Yeah, by providing links or directly in the response so that you do not have to go to all the links for? I think that should be at most levels of nested links. But I think that the smartest approach is to you to pick the proper one, which is the link, which be the most used from this point of response. Anyone? No more questions? So thanks, Malvin, again.
 The next talk will be a restful SPI best practices by Malvina.  Let's give her a big applause.  Welcome everybody.  I'm Malvina. I'm a developer at STXnext,  the biggest Python software house in Europe.  Almost five years ago, I brought my first line of code  and that's how my Python journey began.  When I'm not hacking, I'm trying to spange time actively  at the gym or in the nature.  Okay, so let's begin with a short story.  Some time ago, in one of my previous projects,  I had to make many integrations with many providers.  And each of them had very different level of APIs.  We are working on module which was offering tickets  for many kinds of events from many suppliers.  At the beginning, we started implementing integration  with the main provider.  Our first task was to implement a simple search.  The endpoint for searching was limited.  The API provider offered us only searching  but the date or text.  So after consultation of our product owner,  we decided to develop the same functionality.  While working on it, we started to see  first little, started to get to know better the API  and started to see first minor issues.  The first surprise was fact that they didn't have paginations.  So in result, we had to store all data on client side.  Other fact, the documentation was so poor  besides the fact that it was really hard to find  any information. This information was incomplete.  For example, there was no info about return object types,  which started to make sense after noticing  that the return object types are not consistent.  Some feeds could start on an empty array  or there was a feed that store a data time object  or a regular event and string with date range for festives.  From our PO point of view, the satisfying was fact  that we didn't display prices on the list view.  This information wasn't returned by endpoint for searching  and calling the other endpoint for all return events  would be too expensive.  So after first branch, we developed something like this.  To cheer up our PO and improve user experience,  our next task was enlarging searching.  We wanted to add filtering and sorting the events.  The API provider wasn't offered as such complicated features,  so to achieve this goal, we decided to store all data  and we wanted to make sure that we could download  our database. We developed the Chrome jobs  that were downloaded events every day at midnight.  Additional advantage of this approach was fact that we could  also download the prices by calling other ad points.  Every frame seems to go well, but it was a calm before the storm.  The problem appeared when all developers and testers  started using in on their own local instances.  It was edge people. The API provider wasn't prepared  for so many codes, so they didn't catch the queries  and in result, they banned our IP addresses.  After this action, this banned us another couple of times.  Another visible dropback was fact that they didn't have  the best environment. The outcome of this was a small disaster.  First of all, there was so many fact data on production,  like special demo events specially prepared  for testing buying the tickets. You have to spend a lot of time  on their side to find it, whereas on our result page,  this data was more exposed.  Also, to prevent buying real tickets,  our API key was locked, but when we wanted to  release our feature, we needed to test buying  real tickets. So, API provider delivered us  other unlock API key. Unfortunately,  some misunderstanding occurred and they unlocked  rank API key. We find it out when a postman  came to our office one beautiful day and delivered us  a ticket. During integration with another  provider, the most surprising were your N names.  They were very un-intuitive. To get the events, you have to go  to slash localization endpoints and event  endpoints was performances  and sorry, I just lost myself  again in the manner of mention of it. Also, data  structure was so messy.  This API was developed without understanding the client's need.  We spent a lot of hours to get  the logic and map the structure of events  to ours. So, the question is  what could the API provider have done better?  One of the answers can be restful  and it's not a problem.  Rest stands for representation of the  answer. It's an architectural style  with a set of constraints that allows a simple communication  between two systems, typically a client and the server, where  communication between these is based on HTTP.  And now is the question for you guys, who  is the most important part of the project?  I thought so. The form  describes six architectural constraints. Clean  server architecture style is the basic restriction for restful  application. The system is disconnected. For example,  clients are not concerned with data storage and the servers are  not concerned with user interface or user  interface. The question is to separate  architecture and responsibilities in both environments.  In Wizard, we improved the portability of the client's  code by simplifying the server's components.  Stateless is the constraint to the client's server  interactions. One client can send multiple requests to the  server and each of them must be independent. This means that  the client's request to the server must contain  only that information to service the request.  In order to improve network efficiency,  rechart data from server are explicitly  labeled as cacheable or noncacheable.  We can cache response messages on client on the server or above  side. The rule to create a cache can be different for each  user. The user can use the cache after a given period of time  or whenever there is a change in some state.  Uniform interface is a central feature that distinguishes  restful architecture style from other network-based styles.  It's a well-defined contract for communication between  client and the server.  The four guiding principles of uniform interface are  the first one is to identify and get resources,  manipulate and get resources through representations,  send descriptive messages, and hypermedia as the engine of  application state. The layer system style allows  an architecture to be composed of hierarchical layers.  There can be multiple layers of software involved and  retrieving information. So server may improve  or increase the network소� stray.  It takes solutions from employer  to provide the way, balancer, firewall, or by providing  short caches.  Codes on demand is entirely constrained.  The server can have the functionality of clients  by transfer of executable code.  Codes on demand are always  applets, or client-side scripting languages.  Complaining with these constraints,  REST introduced certain architectural properties.  Web service APIs that add here to the REST architectural  constraints are called RESTful APIs.  Many people would go on to say that RESTful API uses only  HTTP adjacent.  And all of this is important, and it's part of RESTful itself.  But to consider an API RESTful, it  must truly follow all the rules defined in REST architecture.  It's worth to be familiarized with learn how to try  its own REST maturity model.  A maturity model is a MIPE that guides users  into level-increasing levels of compilance  with some definition, methodology, or architecture.  The REST maturity model is the same time of improvement map  for building web services.  This maturity model knows four levels  where the last one designates a truly RESTful API.  The concept of REST is to separate the API structure  into logical resources.  Individual resources are identified by your REST.  During design, the API resources don't directly map one  to one your database into resources.  You don't want to irrelevant implementation details  in your API.  Use sensible resource names.  For example, in our ticketing module,  some of the resources could look like this.  You should notice that all of these resources  are now not verbs.  Also, don't mix up singular and plural nouns.  Keep it simple and use only plural.  Use one case convention.  There are three main case conventions,  common case, next case, and spinal case.  As a Python, it would probably pick the snake case.  Also, avoid apostrophes, spacing,  and other exotic characters.  Resources are identified by your REST and manipulated  by HTTP operations.  Post-get push-patch delete corresponds  to create-read-update and delete.  So remember, get method should not alter the state.  To sum up, if you want to retrieve a list of events,  use method get or resource event.  To get a specific event, just add ID to this resource.  And if you want to create the event use pod method  on resource events, to update some event use  put or patch method on the resource of concrete event,  and to delete use method delete.  If you have a relations, good practice  is to use super sources, but make at most two levels  of nested API object.  Operations under resources look the same.  Also, you can consider add to your response  related resource representations.  By default, use only this almost access together.  Avoid accumulating too much information,  and don't embed collections if it has too many components.  By just approach, you then can avoid making extra API calls  and improve efficiency.  And if that feature would be in our API,  in my previous project, you would  have had prices on the list view from the beginning,  and our API would be happy.  To describe return values, our API  should return relevant HTTP status codes.  Of course, we should use this one now.  For example, 200 other cases can be used to a successful get.  When we create a successfully API,  should successfully a resource, API should return 201 created.  In this case, we should add to our response related URL  to the just created resource.  To handle the errors, also we should use HTTP status codes,  like here in an example.  Also, to inform user what happened,  put show a useful error message.  For large data sets, limit the return amount of data  as important.  Try to make advance searching just  add query parameters to the URL.  If you want to enable fortralling, just use attribute  name with an equals sign and expected values.  The sort results use parameter sort  or ordered by with the name of attributes  on which sorting will be performed.  This will understand the just add  hyphen before the attribute name.  Sometimes basic filtering does not fit our needs.  Then we should consider providing full text search,  calling by multiple fields.  A nice approach is to enable to think  which are in response.  Clients can save valuable memory by retrieving  only needed information.  There's parent fields that takes a comma separated  fields to include.  According to the rest theory, actions or resources  are constrained to create read update delete.  But in real life, there are some cases  that doesn't fit those rules.  For example, if you want to implement a multi-resource  search, compute or convert something.  For these exceptions, you should use verbs as URL names  rather than an ounce.  We should use URL names that are the most fitting.  But also carefully describe these exceptions  in your documentation.  It's hard to foresee all resources presentation.  Almost each evolve after time.  It's natural to version your API.  There are many best approaches for versioning APIs.  The most famous is to include version.  And URL path.  But other piece of work is it by adding  version in HTTP header.  Oh, and don't advance default versioning.  Paginate the results to make response easier to handle.  Even if at the beginning you don't have large amount of data,  you don't know how it will be in the future.  And do this in an early design phrase is easier.  So there's also no one paging mechanism.  You can add paging to your request by URL or HTTP  header.  In response, you can return pagination  and envelope or header.  For example, rate or length header.  As the result, we can easily navigate it through the pages  and consume the results.  Both client and server needs to know which format is used  for communications.  We can use HTTP headers dedicated for this.  In content type, define the request format  and accept specified return format.  In response messages, enable pre-preprint.  It will be easier to debug or analyzing your API  through the browser.  Try evolving your response messages.  In most cases, an unnecessary extra layer  in the response messages.  HyperMedia is the engine of application state.  It's the most omitted constraint.  But you should try to use it in your API.  Just provide links to your API.  If you don't have links in your API,  your API is still be useful.  But after providing them, it's more discoverable  and self-descriptive.  For example, if you want to find Madonna concert  in some events portal, you have to go to search page,  type Madonna, and pick proper event.  To do this by your API, first you have to go to documentation  and find endpoint for searching.  And then you have to do the same to find out  how you can display a proper event.  And after providing the links, all you need to know  to find Madonna concert by API is your root address.  You can interact with API just like you interact with browser.  Documentation is an important thing.  Documentation is an important part of API.  It should enhance in commerce and make life easier  for current users.  So describe all features needed in formations.  Put the examples of usage or request or responses.  Use code for this and your API will be easier to debug.  Documentation should be easy to find and user friendly.  Try not to use developer jargon and make it pretty.  From my experience point of view,  I have this strange feeling that many developers  are in kind of student state of mind.  I mean they're not business nor user focus.  They forgot they developed feature for real users,  which is totally opposite to 100% back free demo path,  especially created to satisfy professor need and pass some  classes.  And there is a high chance that it will fail each other way.  And I'm sure you know what I'm talking about  because we all did this.  So remember, have a doubts.  Make sure your code follow the best practices.  Even the slices.  Investigate how some part of your API should look like.  Check how web giants do this.  Use Google search to solve problem  or use this issue to initiate the small talk in the kitchen  or put this subject in your team.  Use best practices where they make sense.  But of course, don't get stuck in an infinitive loop  of researching best approaches.  Think, comment, and go.  The most important part is fact that you  are thinking about the user.  Thank you.  Thank you.  We have time for questions.  I've got a question.  When you talk about links in your API,  did you use or is specified anywhere the names?  The examples of links?  The example of links.  For example, the metadata or?  Yes, you should use your name names and the method.  And you can also provide a short description  about what this link is.  Thanks.  Good questions.  So you mentioned indeed about putting links in the response.  And I guess that's what you indeed do as best practice.  Do you have any recommendation of how nested your response can  be?  I'm sorry.  Can you say something louder?  Yeah, you can hear me now.  Yes, better.  OK, so I was wondering how nested  can response be?  So how many layers of nesting you can do?  By providing links, yes.  Yeah, by providing links or directly in the response  so that you do not have to go to all the links for?  I think that should be at most levels of nested links.  But I think that the smartest approach is to you  to pick the proper one, which is the link, which  be the most used from this point of response.  Anyone?  No more questions?  So thanks, Malvin, again.
Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__0_803.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__804_1247.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__1248_4283.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__4284_4331.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__4332_4439.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__4440_4523.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__4524_4631.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__4632_9527.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__9528_9791.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__9792_10283.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__10284_13091.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__13092_13151.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__13152_13787.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__13788_14627.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__14628_15875.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__15876_16343.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__16344_16763.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__16764_17795.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__17796_18263.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__18264_26099.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__26100_26819.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__26820_29555.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__29556_29759.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__29760_31547.png Malwina_Nowakowska_-_RESTful_API_-_Best_Practices__31548_35000.png
The next talk will be a restful SPI best practices by Malvina. Let's give her a big applause. Welcome everybody. I'm Malvina. I'm a developer at STXnext, the biggest Python software house in Europe. Almost five years ago, I brought my first line of code and that's how my Python journey began. When I'm not hacking, I'm trying to spange time actively at the gym or in the nature. Okay, so let's begin with a short story. Some time ago, in one of my previous projects, I had to make many integrations with many providers. And each of them had very different level of APIs. We are working on module which was offering tickets for many kinds of events from many suppliers. At the beginning, we started implementing integration with the main provider. Our first task was to implement a simple search. The endpoint for searching was limited. The API provider offered us only searching but the date or text. So after consultation of our product owner, we decided to develop the same functionality. While working on it, we started to see first little, started to get to know better the API and started to see first minor issues. The first surprise was fact that they didn't have paginations. So in result, we had to store all data on client side. Other fact, the documentation was so poor besides the fact that it was really hard to find any information. This information was incomplete. For example, there was no info about return object types, which started to make sense after noticing that the return object types are not consistent. Some feeds could start on an empty array or there was a feed that store a data time object or a regular event and string with date range for festives. From our PO point of view, the satisfying was fact that we didn't display prices on the list view. This information wasn't returned by endpoint for searching and calling the other endpoint for all return events would be too expensive. So after first branch, we developed something like this. To cheer up our PO and improve user experience, our next task was enlarging searching. We wanted to add filtering and sorting the events. The API provider wasn't offered as such complicated features, so to achieve this goal, we decided to store all data and we wanted to make sure that we could download our database. We developed the Chrome jobs that were downloaded events every day at midnight. Additional advantage of this approach was fact that we could also download the prices by calling other ad points. Every frame seems to go well, but it was a calm before the storm. The problem appeared when all developers and testers started using in on their own local instances. It was edge people. The API provider wasn't prepared for so many codes, so they didn't catch the queries and in result, they banned our IP addresses. After this action, this banned us another couple of times. Another visible dropback was fact that they didn't have the best environment. The outcome of this was a small disaster. First of all, there was so many fact data on production, like special demo events specially prepared for testing buying the tickets. You have to spend a lot of time on their side to find it, whereas on our result page, this data was more exposed. Also, to prevent buying real tickets, our API key was locked, but when we wanted to release our feature, we needed to test buying real tickets. So, API provider delivered us other unlock API key. Unfortunately, some misunderstanding occurred and they unlocked rank API key. We find it out when a postman came to our office one beautiful day and delivered us a ticket. During integration with another provider, the most surprising were your N names. They were very un-intuitive. To get the events, you have to go to slash localization endpoints and event endpoints was performances and sorry, I just lost myself again in the manner of mention of it. Also, data structure was so messy. This API was developed without understanding the client's need. We spent a lot of hours to get the logic and map the structure of events to ours. So, the question is what could the API provider have done better? One of the answers can be restful and it's not a problem. Rest stands for representation of the answer. It's an architectural style with a set of constraints that allows a simple communication between two systems, typically a client and the server, where communication between these is based on HTTP. And now is the question for you guys, who is the most important part of the project? I thought so. The form describes six architectural constraints. Clean server architecture style is the basic restriction for restful application. The system is disconnected. For example, clients are not concerned with data storage and the servers are not concerned with user interface or user interface. The question is to separate architecture and responsibilities in both environments. In Wizard, we improved the portability of the client's code by simplifying the server's components. Stateless is the constraint to the client's server interactions. One client can send multiple requests to the server and each of them must be independent. This means that the client's request to the server must contain only that information to service the request. In order to improve network efficiency, rechart data from server are explicitly labeled as cacheable or noncacheable. We can cache response messages on client on the server or above side. The rule to create a cache can be different for each user. The user can use the cache after a given period of time or whenever there is a change in some state. Uniform interface is a central feature that distinguishes restful architecture style from other network-based styles. It's a well-defined contract for communication between client and the server. The four guiding principles of uniform interface are the first one is to identify and get resources, manipulate and get resources through representations, send descriptive messages, and hypermedia as the engine of application state. The layer system style allows an architecture to be composed of hierarchical layers. There can be multiple layers of software involved and retrieving information. So server may improve or increase the network소� stray. It takes solutions from employer to provide the way, balancer, firewall, or by providing short caches. Codes on demand is entirely constrained. The server can have the functionality of clients by transfer of executable code. Codes on demand are always applets, or client-side scripting languages. Complaining with these constraints, REST introduced certain architectural properties. Web service APIs that add here to the REST architectural constraints are called RESTful APIs. Many people would go on to say that RESTful API uses only HTTP adjacent. And all of this is important, and it's part of RESTful itself. But to consider an API RESTful, it must truly follow all the rules defined in REST architecture. It's worth to be familiarized with learn how to try its own REST maturity model. A maturity model is a MIPE that guides users into level-increasing levels of compilance with some definition, methodology, or architecture. The REST maturity model is the same time of improvement map for building web services. This maturity model knows four levels where the last one designates a truly RESTful API. The concept of REST is to separate the API structure into logical resources. Individual resources are identified by your REST. During design, the API resources don't directly map one to one your database into resources. You don't want to irrelevant implementation details in your API. Use sensible resource names. For example, in our ticketing module, some of the resources could look like this. You should notice that all of these resources are now not verbs. Also, don't mix up singular and plural nouns. Keep it simple and use only plural. Use one case convention. There are three main case conventions, common case, next case, and spinal case. As a Python, it would probably pick the snake case. Also, avoid apostrophes, spacing, and other exotic characters. Resources are identified by your REST and manipulated by HTTP operations. Post-get push-patch delete corresponds to create-read-update and delete. So remember, get method should not alter the state. To sum up, if you want to retrieve a list of events, use method get or resource event. To get a specific event, just add ID to this resource. And if you want to create the event use pod method on resource events, to update some event use put or patch method on the resource of concrete event, and to delete use method delete. If you have a relations, good practice is to use super sources, but make at most two levels of nested API object. Operations under resources look the same. Also, you can consider add to your response related resource representations. By default, use only this almost access together. Avoid accumulating too much information, and don't embed collections if it has too many components. By just approach, you then can avoid making extra API calls and improve efficiency. And if that feature would be in our API, in my previous project, you would have had prices on the list view from the beginning, and our API would be happy. To describe return values, our API should return relevant HTTP status codes. Of course, we should use this one now. For example, 200 other cases can be used to a successful get. When we create a successfully API, should successfully a resource, API should return 201 created. In this case, we should add to our response related URL to the just created resource. To handle the errors, also we should use HTTP status codes, like here in an example. Also, to inform user what happened, put show a useful error message. For large data sets, limit the return amount of data as important. Try to make advance searching just add query parameters to the URL. If you want to enable fortralling, just use attribute name with an equals sign and expected values. The sort results use parameter sort or ordered by with the name of attributes on which sorting will be performed. This will understand the just add hyphen before the attribute name. Sometimes basic filtering does not fit our needs. Then we should consider providing full text search, calling by multiple fields. A nice approach is to enable to think which are in response. Clients can save valuable memory by retrieving only needed information. There's parent fields that takes a comma separated fields to include. According to the rest theory, actions or resources are constrained to create read update delete. But in real life, there are some cases that doesn't fit those rules. For example, if you want to implement a multi-resource search, compute or convert something. For these exceptions, you should use verbs as URL names rather than an ounce. We should use URL names that are the most fitting. But also carefully describe these exceptions in your documentation. It's hard to foresee all resources presentation. Almost each evolve after time. It's natural to version your API. There are many best approaches for versioning APIs. The most famous is to include version. And URL path. But other piece of work is it by adding version in HTTP header. Oh, and don't advance default versioning. Paginate the results to make response easier to handle. Even if at the beginning you don't have large amount of data, you don't know how it will be in the future. And do this in an early design phrase is easier. So there's also no one paging mechanism. You can add paging to your request by URL or HTTP header. In response, you can return pagination and envelope or header. For example, rate or length header. As the result, we can easily navigate it through the pages and consume the results. Both client and server needs to know which format is used for communications. We can use HTTP headers dedicated for this. In content type, define the request format and accept specified return format. In response messages, enable pre-preprint. It will be easier to debug or analyzing your API through the browser. Try evolving your response messages. In most cases, an unnecessary extra layer in the response messages. HyperMedia is the engine of application state. It's the most omitted constraint. But you should try to use it in your API. Just provide links to your API. If you don't have links in your API, your API is still be useful. But after providing them, it's more discoverable and self-descriptive. For example, if you want to find Madonna concert in some events portal, you have to go to search page, type Madonna, and pick proper event. To do this by your API, first you have to go to documentation and find endpoint for searching. And then you have to do the same to find out how you can display a proper event. And after providing the links, all you need to know to find Madonna concert by API is your root address. You can interact with API just like you interact with browser. Documentation is an important thing. Documentation is an important part of API. It should enhance in commerce and make life easier for current users. So describe all features needed in formations. Put the examples of usage or request or responses. Use code for this and your API will be easier to debug. Documentation should be easy to find and user friendly. Try not to use developer jargon and make it pretty. From my experience point of view, I have this strange feeling that many developers are in kind of student state of mind. I mean they're not business nor user focus. They forgot they developed feature for real users, which is totally opposite to 100% back free demo path, especially created to satisfy professor need and pass some classes. And there is a high chance that it will fail each other way. And I'm sure you know what I'm talking about because we all did this. So remember, have a doubts. Make sure your code follow the best practices. Even the slices. Investigate how some part of your API should look like. Check how web giants do this. Use Google search to solve problem or use this issue to initiate the small talk in the kitchen or put this subject in your team. Use best practices where they make sense. But of course, don't get stuck in an infinitive loop of researching best approaches. Think, comment, and go. The most important part is fact that you are thinking about the user. Thank you. Thank you. We have time for questions. I've got a question. When you talk about links in your API, did you use or is specified anywhere the names? The examples of links? The example of links. For example, the metadata or? Yes, you should use your name names and the method. And you can also provide a short description about what this link is. Thanks. Good questions. So you mentioned indeed about putting links in the response. And I guess that's what you indeed do as best practice. Do you have any recommendation of how nested your response can be? I'm sorry. Can you say something louder? Yeah, you can hear me now. Yes, better. OK, so I was wondering how nested can response be? So how many layers of nesting you can do? By providing links, yes. Yeah, by providing links or directly in the response so that you do not have to go to all the links for? I think that should be at most levels of nested links. But I think that the smartest approach is to you to pick the proper one, which is the link, which be the most used from this point of response. Anyone? No more questions? So thanks, Malvin, again.
Some time ago, in one of my previous projects, I had to make many integrations with many providers. And each of them had very different level of APIs. We are working on module which was key. Unfortunately, some misunderstanding question is what could the API provider have done communication between these is based on HTTP. And architecture and responsibilities in both above side. The rule to create a cache can be REST introduced certain architectural properties. architectural constraints are called RESTful building web services. This maturity model knows RESTful API. The concept of REST is to separate example, in our ticketing module, some of the convention. There are three main case have had prices on the list view from the beginning, and our API would be happy. To API should return 201 created. In this case, we have links in your API, your API is still be browser. Documentation is an important thing. Documentation is an important part of API. It your API will be easier to debug. Documentation my experience point of view, I have this strange your code follow the best practices. Even the should look like. Check how web giants do this. When you talk about links in your API, did you examples of links? The example of links. For directly in the response so that you do not have