 Well, it comes to the third part of lecture 15 and 16. In the last part, we learned about, theoretically, what rest is about, what the different constraints are. Then I gave you the example of how this works with websites. But this is still rather confusing. So that's why now we actually go in and design a web application. So we will not yet implement anything. This is really just a design, how it's structured. In lecture 17, in the last part, we'll then actually implement this in Node.js and Express to show you how this works. And we'll just do the server side part, the back end. So this has nothing to do with HTML, with graphical things, with anything running on the client. We just do a server that handles requests and sends responses back. What we'll do is a fairly simple program. We just want to build an application that allows users to handle to-do notes, so you can sort of create your own to-do list, tick off things, and so on. Now, to-do notes are our resources. So we create them, we read them, and so on. And ideally, something you'll see all over the place is the CRUD acronym. So that stands for Create, Read, Update, Delete. So those are typical operations you want to do with a resource. Depending on our application, we might only allow some of them. So for example, in many applications, you cannot delete things. You can only create them. But in our case, we want to say, OK, to-do notes, you should be able to create, to read, to update, which means change or delete them. And we should be somehow supporting multiple users. So it's not a single user application, but there are multiple users, and each user has his or her own notes. As discussed, we only look at the back end. So you could, since we are following client server and we follow the layered style, you could implement many different front-ends for our to-do application, for example, an Android application, an iOS application, a website, or a regular desktop application written in Python, for example. And of course, since this is the topic, we want to build the whole thing in a restful way. We want to build a restful API. What we'll do is we assume that our back end is hosted, is located at the following URL. So everything is on HTTP colon double slash to-do-app.com. That's just because we will be designing URLs, basically. In reality, of course, this depends. You might buy your own domain, or you deploy something on the cloud, and then you'll get a different URL. But that doesn't matter for our case. So the first thing is, what are our resources? So we want to have resources in rest or in HTTP. So what do we do in our case? We build a to-do app. So obviously, we have to have the to-do notes. And we want to have multiple users. So that's another resource. And now we go into the different constraints. So constraint 5.1 says we should be able to identify our resources through a uniform interface. And if we look at the checklist number 3, link number 3, I've opened it up, there are different things. And one of them is use a noun for the resource name and use the plural. So that's a very common style you'll often see, which means if we want to identify, if we want to access our users, we do slash users. HTTP to-do-app.com slash users. That should somehow give us access to all the users. If we want to access to all the notes, we might, for example, do slash notes. If we want to access one specific user, then we do slash users slash ID. So if you want to access user number 5, we would do users slash 5. Again, that's a recommendation in the checklist here. Use your eyes that don't change. So a common way to identify a single resource is to use the ID that is, for example, the primary key in the database table. Because you know that our user might change, for example, the password or the address or whatever, but hopefully the primary key in the database does not change. So that's the best way to identify a resource because there's guarantee that this will not change in the future. And then we could say, again, that's a common way to relate resources to each other. If we want to have all the notes for one specific user, then we do slash users slash ID. This gives us user number 5, for example. And if we then do slash notes, we get all the notes for user 5. So this is the way we'll structure our URIs. And this is the way we'll access our resources. So from the checklist, we say plural nouns are used for all the resources. That's what we do. Resources slash ID is used for one specific resource. And sub-resources, what we have here, slash notes, they help us to show relations. So notes is here related to one specific user. So that's a common way to show that notes and users are somehow related here. Now, the next constraint, 5.2, is use representation of the data. And there are lots of things we could do. We could send plain text. We could use JSON. We could use HTML, XML. We could send a picture of how the user looks like. But one common style in the internet, which we have used so far for a good reason and is also recommanded in the checklist, is use the JSON format, because it's easy, because it's supported by most languages. That's why we should do it. So this means when we, for example, when we want to have all the users, we will get a JSON response, an array of all the users. When we want to change something, we want to change a user, for example. Our request will also be JSON data. So we'll just say, OK, please change the user according to this JSON format. For example, by sending a JSON object that just contains a new password attribute. And then the server knows, OK, I have to replace the password of the user. This will become more concrete when we implement the whole thing in lecture 17. So from the checklist, there is recommended to use JSON as a request response data format. That's nowadays almost a standard, I would say. Now, each request and response should be self descriptive. That's constraint number 5.3. And the checklist recommends to use the HTTP verbs to describe what we want to do. And that's something I have already discussed in the previous part. That's very common. That, for example, if we now do get slash users, the server will read. It will return the list of all users. So when we do a get request to this URL, the server should return a JSON representation of all the users. If we do get user slash 5, we get a JSON representation of the user with ID 5. If we now instead do post to slash users, so same URL as above, but a different verb, now we tell the server to create a user. So instead of reading it, we create a new one. And there are differences on what is returned, but that's, again, something we'll discuss later. Now if we do get user slash 5 slash nodes, we get all the nodes for user number 5. So again, we get a JSON representation of all the nodes that belong to user 5. If there is no user 5, we don't get anything back. We get an error, probably. Now we get into some verbs we haven't touched upon yet. And the first one is put. If we do put to users slash 5 slash nodes slash 10, so first of all, this is node number 10 for the user number 5. And put is usually an update request. So we tell the server, please go to node number 10 for user 5 and update it, change it, according to the data I sent to you. And then finally, that's a bit more descriptive. If I go delete users slash 5, then the server should take this user and delete him or her. So the verbs here, they really tell the server what to do exactly. So that's how we design it. HTTP and the implementations allow a lot of different things. So I could implement something that says, when you do a get request, please delete all the users. It's possible to do that. So this is just a style that we say, if we follow this convention, if we implement our API in this way, it will be more understandable. The requests are self descriptive. And now finally, in connection to this, I would like to remind you that HTTP verbs have certain properties. So we said in the beginning that the get request should be safe. Nothing should change. A get request should be cacheable, can be reused. Delete and put requests are idempotent. So if you run them multiple times, the result on the server is exactly the same. So what does this mean? If we do a get request to slash users, we get a list of all the users. And the important thing is on the server, nothing changes. So I will not anyhow modify the users or anything else. It should stay exactly the same as before. The put request is idempotent. So if I request the server to update node number 10, if I do that twice, it should be the same effect as if I do it once. Of course, the important thing is always as long as there has not been any other request in between. So for example, if I update node number 10, then someone deletes it and then I send the same request and of course I will get a different result. The first time it will do an update, the second time it will probably give me an error because the node has been deleted. So idempotent means if you call it multiple times without any other thing happening, then the result is the same. So that's what these things mean. We can discuss that also more when we get again into implementation. Now, we are not done yet with Constraint 5.3. We said each request response should be self descriptive. One way of being self descriptive in HTTP is to use the standard HTTP status codes when you reply. So if there is an error, for example, I want to update something that doesn't exist, node number 10 does not exist, then you should never send back a 200 code because 200 says everything is okay. Instead, you should send something back with 400 because there has been an error, the node doesn't exist and probably the best answer would be 404 not found. We have not found this node, we cannot update it. And similarly, if everything is okay, then please send back a 200 code and nothing else. What is very common sort of standard is to send back 200 when it's a get request. So it's just okay, everything is fine. And we use 201 when we do a post request. 201 is created. So I have successfully created something on the server, send back 201. If there's anything the client has done wrong, the request is wrong, something is not allowed, you're not authorized, send back a 400. If something breaks on the server side, there are exceptions, there's an error in the database, send back a 500 code. So those are the conventions for the response. Now, the interesting one, resources should contain links. So that's the hate to us constraint number five, four. The checklist tells us provide links so that clients can easily navigate to related resources, use standard link types if possible. Most people ignore this and most APIs do not do that. So it's also for this course in the assignment, I do not require you to implement that. But just to give you an impression of how this could look like, if I do get user slash five, I ask the server to return the user number five in JSON format. And that's good, for example, look like that. I send back JSON, it's an object. The username is Grisha, the ID is five. So that's just the user information. And then I send back a number of links. So I say, okay, here's an array of links and you can do different things with this. For example, if you do get this URL, then you get to self, you get to the same user. So that's kind of the pointer to the same resource. If you do a get request to slash eight, you get to the next user. So there seems to be no user five and six, so the next one is eight. If you want to get rid of this user, if you want to delete, you can do users slash five with a delete method. So I basically tell the client or whoever calls this link, what else to do that is somehow related to this user. And the important thing is the link is not just like an HTTP or HTML documents, it's not just the URL, but we need to have information on the method because that tells us what we can do with it. There are standard links, for example, is self next and delete, I actually standardized, but the standardization is not often very useful. So I actually won't go into detail there. And as I said, a lot of people, a lot of organizations simply ignore this constraint. Technically it means they're not really doing rest, but it's just very often unclear what exactly or how to handle these links. Okay, what I've covered so far is only constraint number five. So we have this uniform interface which has the four sub-constrains, but there are a lot of other things. So the question is what about them? How do we look at them in our API design? And there are a number of them, of course. Client server is just given by HTTP. So if we say that our application is using the HTTP protocol as we do here, then we automatically are doing client server. Stateless and layered system actually depend on how we implement the solution later on. So far we have just designed how the URLs look like and we have sort of decided what the logic is. If we do get, we return something. Whether or not they're stateless or they're layered depends on how we implement it. So for example, if we decide that we want to use cookies to store session information, session cookies are a very common thing. We haven't gone into that. But if we do that, then we are not stateless anymore. So we violate that constraint. But that's purely on the implementation side. So it's nothing in our design. Similarly, if we somehow allow the client to directly access the database without going through our API, then we're not having a layered system anymore. So this is again nothing that has to do with how our interface looks like. Cacheable, that constraint is again something that is given by HTTP. So if we decide to set the response header, we tell the receiver that you can cache this for five days or we don't tell the client and then you cannot cache it. So HTTP automatically has this information. So again, this is something we get from HTTP. And then finally, code on demand is something that is optional. We don't have to do that. So constraint number six, we can ignore. We are still restful. And this is actually, I told you about HTML that is very common to link to JavaScript code, for example. But in backends, this is extremely uncommon. So it's not very common to send code in our JSON response. And this is nothing we do. So these are the rest constraints. Essentially what we looked at now was constraint number five. And that's the most important one for the API design. There are a number of additional things in the checklists that have nothing to do with rest, but they're nevertheless useful and important. And a common thing is to use parameters, to use the query to, for example, allow sorting, paging, field selection and so on. So for instance, we would like to design our API that if we do a get users, we get all the users. And if we additionally add the query sort by, then we get a sorted list back. So in this case, we want to get all users sorted by username, paging. If we tell the server that we want to have page six with a page size of 10, what this means is please only give me users 60 to 69 in the collection. So that's of course what you know from things like Google. You only get a certain number of search results. And then if you go to page five of your search results, you only want to get other search results. So again, it's a very common thing to do. And finally, you might also want to get filtering. So if your resource has a lot of different fields and you're not interested in them, it's common to have this field selection that you say, give me all the users, but actually only give me the username. I'm not interested in anything else. The first two are included in the recommendations in the checklist, field selection is actually not in there, but it's a very common one as well. Then another thing that is not in the checklist, but that is extremely common and useful is to add a version prefix in your API. So instead of saying to do app.com slash users, we would do to do app.com slash v1 slash users. And the idea is your API usually evolves over time, and you might want to change things. And if you have a lot of customers, you don't want to directly break all their implementations. So you don't want to say, okay, tomorrow you have to switch to version two. What you can do instead is if you use this version prefix, you can have multiple versions running at the same time. So we will look at PayPal later. They have version one and two. At some point they just introduced version two, which is different, but of course PayPal has a lot of users. It's about finance, it's about money. They cannot just say, well, please everybody just update your applications tomorrow. So they let version one run for a long time. And now they slowly say, okay, in a year we will get rid of it, but please slowly update. So if you have this version prefix, it just helps you to run your application in the future because you can have multiple versions running at the same time. The next thing, which is a convention, it's not in three. We will use it in this course, is that when you do a post, a put, or a delete request, so you create a user, in this case you update node number 10 for user number five or you delete user number five, our convention is that you also return the resource. So if we look for example at the same case, at the delete case, we want to delete user number five, we could just send back 200. It has been successful, the user is gone, but it's sort of the convention in many cases to say, okay, user number five has been deleted and here is the JSON representation. So this is how the object looks like. And then you still can access the data, but on the server it's deleted. Of course this only makes sense when the representations are small. So imagine you have a video, your resource are videos and they're very large, then maybe you don't always want to return the whole thing. So that's a matter of your application logic. Okay. We have resources, we have HTTP methods, what do we want to use for different things? So we have the two cases, we have the access to the collection of all the resources, so slash users accesses all of our users, slash users slash five only accesses user number five. So the question is what do we want to do for what? If we do a post request to slash users, we want to create a new user. Now, if we would do a post request to users slash five, the logic would somehow mean that we want to create a new user that has ID five. But this is something we typically do not want to allow. So we want the backend or the database to decide how the IDs look like. So this is nothing the user should be able to do. So typically we say a post request to a specific individual resource is not allowed. It should return a 405 error. Now the get request we have covered. If we do get slash users, we get a list of all users. If we do get users slash five, we get a single user with a certain ID. So that's perfectly fine. Put is an update. So we want to change the data that already exists. And we have seen the individual one. If we do put users five, we update the user that has ID number five. If we do instead of put to slash users, it means we are bulk updating. So we're updating all users. And this is a matter of your application again. Many applications do not allow this. They do not want to have bulk update, but it might make sense in some cases to say update all users. I think in our case, this actually does not make a lot of sense, but maybe in other cases it does. Now delete, if I do delete users five, I'm deleting user with ID five. If I do delete to slash users, I actually do a bulk delete. I delete all users. Again, this is a request that in many APIs is not allowed. Either for security reasons, you do not want to allow anyone to delete all the users. It might also be for sort of being careful. So even if the admin, for example, maybe should be allowed to do this, you might not want to allow this request just to avoid that someone does it by accident. And then there's an interesting thing to discuss about delete in general. Some resources you should not be able to delete. So a good example are talking about finance, talking about PayPal. In many cases, you do transactions. You transfer money from one place to another. You should not be able to delete transactions because you might still, for example, tax reasons, you might still want to be able to see the history of all the transactions. So there are many cases where, for example, a delete request might not make sense. Similarly, it could also be for put, you might not want to allow it to change transactions if they have been created, for example. So this, which ones you allow or not, depends a lot on the individual case or application. Apart from the method not allowed, the post to an individual resource, that rarely makes sense. Now, the important thing is remember that we keep these URLs. So we always have the same kind of URL, plural noun and then individual ID, and then the verb defines what exactly we do with the resource. We don't do something like get all users or create new users. So we don't put, we don't describe the method within the URL. That's another style that has been used in the past, but this is very ugly and unrest, and it's actually much harder to understand because you need to know all the different endpoints. Here, it's enough to see the verb and to see the resource or the URL, and you understand what it does. Okay, so now if this, we have designed this to do application, the next lecture will go into actually implementing it. So we'll sit down and implement this. And that's it for part three of this lecture. In the final part in part four, we will look at the PayPal API, which is a good example of a RESTful API. And we might look at another one just to show you how these things are designed in detail, in practice. And you'll recognize a lot of the things that we have got through the naming, for example.