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