Eve: Building RESTful APIs with MongoDB and Flask Transcripts
Chapter: Fine-tuning your REST service
Lecture: Conditional requests
0:00 By default, all API responses include an etag header.
0:04 An etag is a hash value representing
0:07 the current state of the resource on the server,
0:10 and it is useful for a variety of reasons.
0:14 Clients are not allowed to edit or delete a resource
0:17 unless they provide an up to date etag
0:20 for the resource they are attempting to update.
0:24 This prevents overriding items with obsolete versions.
0:29 Let's see this workflow in action
0:31 here we have a request to patch a specific document.
0:35 We want to change the last name to a new value,
0:38 and we aren't providing any etag in the headers.
0:43 By the way, you provide an etag by using the if-match header.
0:48 But right now, we are sending a simple request with no etag for the document.
0:54 When we try this command, we get back a precondition required error,
1:00 which means, as you can see here in the massage
1:03 to edit a document its etag must be provided using the if-match header.
1:08 Here I have a second request where I'm doing the same thing,
1:12 but I'm passing an actual if-match header,
1:15 but I am simulating that I don't know the current version
1:19 of the etag on the server, just passing around the string here,
1:22 so let's assume that I actually have
1:25 a cached copy on my client of this person here,
1:29 but the etag I have is not up to date with the one on the server
1:33 somebody else updated the document
1:35 since the last time I downloaded this person.
1:38 If I try to send this patch in I still get an error but it is a different one
1:43 it is precondition failed and the message is telling me
1:47 the client and server etags don't match.
1:50 So if I don't provide an etag, I'm not allowed to update the document
1:54 if I provide a wrong one, I'm also not authorized to update the document.
2:00 Now let's try, here I am doing the same thing
2:04 and I'm actually passing an if-match header with supposedly correct value
2:11 this etag should match the etag on the server for this person,
2:16 let's try to patch in and we get an okay response
2:20 and the document has been updated.
2:22 By the way, the etag is returned and it is a new one,
2:26 because, of course, the hash has changed on the server,
2:29 so the next time I try an update or a delete,
2:32 I will have to use this etag because this is the most up to date
2:37 and matches the one on the server.
2:39 This feature is generally called concurrency control,
2:43 and again, its goal is to prevent clients to overwrite
2:48 the document on the server with obsolete versions.
2:52 Now, concurrency control is a powerful feature,
2:55 it is especially important when there are many clients competing for updates
2:59 now depending on your use case,
3:01 you might not want this complexity in your service
3:04 you would like to be able to disable this feature
3:08 and have clients to simply perform edit request
3:11 without any need to provide an if-match header, you can do that.
3:16 Let's go back to our editor and simply disable concurrency control
3:23 by setting if-match to false.
3:26 If we save, restart, and we go back to our Postman client,
3:32 if I go back to our original request here
3:35 where I had no header and still performing a patch
3:39 on a specific document with a new value,
3:45 if I send this, I should get an okay response now
3:50 and the document has been updated,
3:52 let's try a get request on the same endpoint
3:55 last name has been updated.
3:58 All right, we now know how to switch concurrency control on and off
4:03 by setting the if-match setting to true or false.
4:07 However, these two options are mutually exclusive
4:10 sometimes it would be nice if clients could actually decide
4:14 whether the server should check the if-match header or not.
4:17 Well, it turns out that's possible
4:20 and again, it is simply a setting a keyword in our settings file.
4:26 Let's go back to an active if-match check on the server
4:34 but let's add a new setting and force if-match default value is true.
4:41 If you set it to false, it will let the client decide
4:45 how the server should behave when our edit request comes in.
4:49 If the client has the if-match header in its request,
4:53 then check on the etag will be performed by the server.
4:56 If on the contrary, the request has no if-match header,
5:00 no check will be performed by the server.
5:03 Lastly, you have the option to change the key used for the etag,
5:07 in Json payload, you might not like underscore etag here,
5:12 some people have been asking to remove the underscores for example,
5:15 or they want to use a different keyword.
5:17 You can do that by simply setting etag = whatever value you prefer here,
5:23 for example, simply etag without the underscore,
5:25 let's save, relaunch, go back to our get request.
5:32 Etag has no underscore anymore.
5:36 This is probably the right time to mention
5:37 that you can also change the keys for the other meta fields,
5:42 like updated and created.
5:45 You do that by setting the date created and last updated keywords
5:51 in your settings file.
5:53 Here we are again removing the underscore from the the default values.