RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Content negotiation
Lecture: Concept: Negotiating renderer
0:01 Time to review the concepts behind content negotiation
0:04 and using our multiple content renderers to create a negotiating renderer.
0:11 The idea is we would like to provide multiple return types from the web API,
0:15 we return one object and it gets converted based on what we've asked for;
0:19 so, maybe we go and we ask for application/ json
0:23 and you can see at the bottom here of postman,
0:25 we got some kind of json response, exactly what we asked for.
0:29 On the other hand, if we ask for text/ csv, well text comes back,
0:33 and if we ask for image/ png, the image renderer kicked in
0:38 and it gave us back our image, this is to the same url for each one of these,
0:43 and it's the negotiating renderer selecting
0:45 which specific content type renderer was activated.
0:49 So creating one of these, it's pretty simple really,
0:52 it's just the composite pattern applied to these renderers.
0:56 So here's a simplified version, we've got a negotiating renderer factory
0:59 and we have a renderer look up, so we're looking up given a content type
1:03 what renderer should be used to generate that,
1:07 so this is just a dictionary and we have the ability to add renderers
1:10 given a content type in a renderer, we kind of strip off the white space
1:15 and case sensitivity of it, and map that particular renderer to that content type.
1:19 Then we have just this standard call really delegate to the renderer function,
1:25 now renderer gets a little bit interesting, if we're given a value
1:29 and we go and get the request and we have to say give us the request,
1:32 give us the headers and get the accept header, right, what would you like,,
1:37 what would you like us to give you in terms of format?
1:41 Now, we saw this was kind of ok, as a single string until it wasn't,
1:44 until somebody asked, said I will actually take the multiple types
1:47 like browsers for example, they don't like that so much,
1:50 so we wrote this parse accept header
1:52 to generate a list of various types that they're asking for
1:54 that list may be and frequently probably is one type.
1:57 Alright, so then we just go through and say
2:00 hey do you have a render for the first type, the second type, third type
2:02 and if we do, great we're going to use it.
2:04 And finally, if we go through all the types and we don't have it
2:06 sorry we have no idea what to do with this,
2:08 you're going to have to adjust your system a little bit.
2:10 Maybe add an adapter, maybe transform it in the API
2:14 to something that we could adapt
2:16 who knows, but we can't give you a renderer right now.
2:18 Then of course, we need to register this,
2:21 so to register it, we have to still create all the individual renderers,
2:24 and create a json one with an adapter, create a car image redirecting one
2:27 or a direct one where it just pulls it down and passes through, however you want,
2:32 I want to create a csv renderer, and this one also needs an adapter
2:35 to figure out how to get cars into dictionaries;
2:38 and then finally, we'll create the negotiating renderer,
2:40 we'll set the accept all renderer, so like json is used if you ask */*
2:44 like if I'll take anything, fine you're getting json.
2:47 And then we're going to add the individual content type renderer,
2:49 so application json goes to json, text/ csv goes to csv,
2:53 image/ png goes to image, right.
2:55 And then finally, this negotiating renderer needs to be installed into pyramid
2:59 so we're going to say a config.add_renderer,
3:02 we're going to call it negotiate, right, you make up that string,
3:05 you can call it whatever you want, but I'm calling it negotiate
3:08 and then, when we want to use it, we just go to our route and we say
3:11 the renderer=negotiate, and it's going to figure out given the type that you ask for
3:15 find the appropriate renderer to turn it back, to send it back to you.
3:20 That's content negotiation in Pyramid.