Beyond GET and POST10:05 with Kenneth Love
Handling PUT and DELETE requests requires a bit more work and control than GET and POST do. Let me show you how to handle these two really useful HTTP methods.
So this video has a new workspace. 0:00 So again, you should close yours and open the new one. 0:02 And then you'll be able to see the get and post methods. 0:05 So like here's the post for courses and the stuff for views. 0:09 I want to talk about what I did in reviews real quick. 0:15 Some of you may have noticed this, 0:20 I kinda left it in to see how your debugging skills were. 0:21 But if you leave your review fields as just course, 0:24 which is fine, then it becomes really hard to turn it into the URL for the course. 0:28 So I actually added a new one called for_course, 0:33 and we just set that to be where the course goes. 0:36 So we never actually reveal like the course's ID which doesn't really matter 0:39 one way or the other, but that's the way that I've been doing it. 0:43 And then inside post, create sends back the record that was created so 0:47 you can just grab the review and add the course to it, send it right through. 0:53 So again, this is in the workspace so you can look through all of it. 0:58 So we've talked get, we've talked about post, and so for 1:01 this one I want to focus on put and delete. 1:05 And again I'm going to do them on courses and 1:08 you can kind of replicate them onto reviews. 1:10 Put requests are for updating records. 1:13 So we're going to be working on here in the course resource on the courses. 1:16 But unlike patch requests, they have to contain all of the data for the record, 1:20 not just the updated pieces. 1:24 So with a patch, you can send in, I need to change the title, and 1:26 send just the title. 1:29 With put you have to send the entire record. 1:31 Now I'm not going to implement patch in this course, but 1:34 feel free to experiment with it if you want to. 1:37 So let's talk about put. 1:39 So first of all i'm gonna marshal this with the course fields. 1:41 Cuz put's always going to be a single record. 1:45 And so then we need to parse the args like usual, so 1:48 self.reqparse.parse_args. 1:53 Make sure the arguments are good. 1:56 And then because of how peewee works, 1:58 we have to kind of write our query a little funny. 2:00 So we'll do query = models.Course.update and we're going to update it 2:04 with the args .where(models.Course.id==id) that was passed in. 2:09 That line's a little long, but whatever I'm just gonna leave it. 2:18 And query.execute to actually run execute to actually run the query. 2:22 And then what do we want to return? 2:30 Well what we wanna do is we want to return, oops no need to type return twice. 2:32 Add reviews and then I wanna go fetch the new model again. 2:37 So models.course.get(models.course.id==id)). 2:43 So add reviews to that. 2:49 Right? 2:52 This lines not long, 73, I read the lines wrong. 2:53 Okay, so, but here's the thing though. 2:55 I am going to do the some of the other ones too. 2:59 This is a put and it's gonna come back automatically with a 200, so that's fine, 3:02 I'm gonna go ahead and specify that. 3:07 But I need to add a header to this. 3:08 So let's put a parenthesis right there, so that we can break this to the next line. 3:10 And we're gonna add a dictionary here at the end. 3:15 So this 200, specifies the status code. 3:18 This dictionary has any additional headers that you want to include. 3:21 So let's include the location header. 3:23 And then inside that location header, we're gonna use url_for. 3:26 And we're gonna say resources.courses.course. 3:28 And the id is going to be equal to the id. 3:33 So close that dictionary. 3:36 Close that tuple that reusing just to hold everything together. 3:38 I'm gonna save that. 3:42 Now, a lot of put is just like post. 3:43 Right? Right, we look up here at post. 3:46 Post and put aren't super different, right. 3:48 Take the args, parse them, and use them. 3:52 Unlike post, where I could do models.Course.create, 3:54 p requires me to do this query thing. 3:56 But we already went over that, so that's cool. 3:58 And I'm gonna actually reuse this pattern for delete as well. 4:01 So I don't mind having something a little different right here. 4:05 You may not have seen the returning of a tuple before, but we can talk about that. 4:08 This one's the response body. 4:13 So this'll be a template, or for right now, 4:16 it's gonna be a thing that gets marshaled. 4:19 So it'll be JSON data. 4:21 This is the status code like we talked about, right? 4:23 So this one's 200, because there's not a status code that relates to, 4:25 I updated everything, put is actually a little bit weird in this though. 4:30 According to the http spec, put should have an empty body. 4:34 So nothing in the body. 4:38 And a status code of 204, which means there's no body, but 4:39 that's not very useful. 4:42 So instead I'm sending back the updated record and a status code of 200, 4:44 to indicate that the body is not empty. 4:48 And finally in the dictionary, like I said, is the different headers. 4:50 So in this view I'm going to send back the location header to 4:54 where the updated record is. 4:57 Which is what you would do with the empty body in the 204. 4:58 It's on the location so they know where to go. 5:01 I'm kind of just mixing these two things up. 5:04 Yeah? Maybe? 5:09 Okay, cool whatever. 5:11 So let's actually take this stuff and let's paste it here into delete. 5:12 Cuz I'm here, I might as well use the delete method, right? 5:19 So we're gonna change this to delete, and we don't have any arguments for delete, 5:22 we just delete stuff. 5:27 So where the Course.id==id. 5:28 And then we're gonna execute that. 5:30 And then, to be good, 5:32 we're gonna send back an empty body and a 204 because that's what it should be. 5:34 And I'm gonna send back a location, but the location's gonna go to go to courses, 5:41 not to course, because this record's been deleted. 5:46 So we just send them on to somewhere new. 5:50 Right? 5:53 We send them on to where the other stuff is. 5:54 And, of course, we can get rid of the parentheses there if we want to or 5:59 you can leave them. 6:03 It's up to you. All right, so let's try this out. 6:04 First of all though, let's create a new post. 6:06 All right. So let's look at our body. 6:10 Let's call this object oriented python. 6:12 And object-oriented-python. 6:17 All right. 6:22 So, there's our body. 6:23 And if we send this post in to, let's make sure that we're not, yeah, 6:25 there we go, okay. 6:30 We send those into courses. 6:31 Then we should get a 200 Okay, and we should get this back. 6:33 You know, while I'm here let's go change something real quick. 6:36 So we can send that back, let's send back 6:41 a 201 and I can send back location URL for 6:46 resources.courses.course', id=course.id and 6:51 for this we should have the parenthesis and 6:58 we'll break it here for that. 7:03 Yeah, cool. 7:11 So that gets us to 80. 7:12 All right. 7:13 Sorry, sidetracked, okay so [LAUGH] we created one and we get back a 200. 7:14 Now, though, we'll get back a 201, which is the created status code. 7:20 So okay, cool, so now I don't want to do a put, and I wanna change some of this. 7:25 So I'm gonna actually change it, so I'm gonna take out that hyphen. 7:31 And i'm going to send this through. 7:35 And I got a 405. 7:38 And that's right. 7:39 That's not allowed. 7:40 Because we're going to courses like that. 7:43 So instead we should go to courses/2. 7:45 All right, let's do a get real quick. 7:51 Yep. So there is that. 7:54 All right so now let's do a PUT, look at our body, look at our URL too. 7:55 Okay, so send that, and now we get back the new one, and we get this. 8:01 And if we look at headers we have a location header. 8:05 So this is the location we would go to to get that new resource. 8:10 Cool, so I go to the update and I got the header, right? 8:14 I really want to stress this, if you're not going to send back body content, 8:18 please, please, please, please, please, please, please, please, 8:22 please send back the location header. 8:26 Because that way users of your API know where to go to get that new data. 8:29 Right? 8:34 And it may not even be the same location that they put to. 8:35 You might let them do /put/update or something, right? 8:38 Like courses/to/update, and that's what they put to. 8:42 But then they have to go back to courses/to to get the record. 8:44 Just tell them where to go, that's all I'm asking for. 8:50 Okay, so now this demo right here, 8:53 this wouldn't be complete without trying the delete. 8:56 This data's gonna be ignored. 8:59 I'm gonna to send it just because it's there, but this data's gonna be ignored. 9:00 So let's hit send on the delete. 9:03 We get back a 204 No Content. 9:06 Which is correct, there should be no content. 9:07 And if we look at headers, our location header tells us to go back to courses. 9:10 Right. No response. 9:14 Got the location, which is where I want to go to. 9:16 Cool. So if I was to go to this location, 9:18 if I was to follow this. 9:21 As I should, right? 9:23 And I do a get and I Send. 9:28 And I look at the body. 9:30 I only have the Python collections that I created before I do not have object or 9:32 a Python that I created. 9:36 So that's what I want to do. 9:38 Okay, so I'm going to build the basics of the review end points between 9:39 these videos. 9:41 I got a lot to show you with them once we got authentication set up. 9:43 You should try to build the put and 9:46 delete methods on the reviews by yourself, see if you can do those. 9:48 Our basic API is complete. 9:53 We have all of the crud operations, and we're ACDP methods and headers like pros. 9:55 Now it's time to batten down the hatches on our API, so 9:59 it can withstand the storms of the open internet. 10:02
You need to sign up for Treehouse in order to download course files.Sign up