Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

More Complex Organization

Ninja doesn’t have strict requirements on where you define things. There’s no expectation about file names. In previous lessons, you’ve seen a single way of organizing your API. in this lesson, you’ll cover tools in Ninja for handling more complex structures.

00:00 In the previous lesson, I showed you a complete set of CRUD operations. In this lesson, I’ll show you a mix of organizational techniques you might use as you build larger interfaces with Ninja. These examples aren’t in the sample code.

00:13 I’m just going to show you the concepts. I will be using a couple of these techniques in later lessons.

00:21 You may find that a lot of your CRUD operations have similar things that have to be done for each. If so, it might be simpler to have a single view handle multiple HTTP operations.

00:33 You can do this in Ninja through the use of the api_operation decorator. It takes a list of HTTP operation names indicating what the view should accept. This can be particularly helpful if you need to write an API endpoint that uses an HTTP operation that doesn’t have a corresponding decorator, for example the HEAD or OPTIONS operations.

00:58 Here’s an example view using the api_operation decorator. The first thing the decorator takes is a list of operations. Then, like the other decorators, it takes a path inside of the view.

01:12 You can check the request.method attribute to see which operation was used.

01:19 In all of the example codes so far, I’ve been using routers and adding them to the NinjaAPI object. You don’t have to do this. You can actually use the API object directly.

01:31 Everything you’ve seen with the router can be done with the API object itself. If you’re writing a smaller application or you’re organizing all of your API calls inside of a single Django app, you don’t need the extra indirection of a router.

01:46 You can skip that step and use the API object itself.

01:52 If you’re not using a router and you’ve declared the API inside of an app, you just import that API object inside of your main urls file and use it inside of the path declaration like you’ve seen so far, no difference there.

02:09 There’s no limit on the number of NinjaAPI objects you create. If you have variations in configuration, you can create and map more than one ninja.

02:19 This can be particularly useful for API versioning. API versioning is the idea that all API calls include a version number in their path or in their header. But I prefer the path.

02:33 If you need to make a breaking change in your API, you change the version number in the path as well. This allows you to support both the old version and the new version for some amount of time.

02:45 That way, programmers consuming your API don’t have to update immediately. How long you keep old versions around is up to you. Consider your audience when you’re making this decision.

02:56 It’s been a while since I’ve done any coding against Facebook’s Graph API, but when I did, they gave eighteen months notice before removing an older version.

03:05 They have lots of users and lots of developers working against their API, so this is just respectful to their time. You can specify a version tag name when you create the Ninja object.

03:17 The default is 1.0.0. I find that awfully verbose and usually knock it down to just 1. The version attribute affects the namespace for reverse lookup.

03:29 This is why the default namespace is api-1.0.0. Like you saw on the previous lesson, the version number tag itself doesn’t impact the path. If you’re going to use version info in the path, you do it manually, like I’ve done here, when you register the path.

03:49 And of course, you can have different routers for each one of your different Ninja objects. This is no different than what you’ve seen so far. And just to reiterate, as I mentioned, the version number changes the namespace,

04:02 so you’d see a different result inside of reverse. By default it’s api-1.0.0. With a new name, it becomes api-2.0, or whatever else you named it.

04:17 Note that the api- part is there automatically.

04:24 If you need another layer of organization, you can add routers to your routers. This impacts your path as well. In the example here, the kraken router gets added to the greyjoy router.

04:35 Then the greyjoy router is added to the Ninja object. The tentacles endpoint will be api-greyjoy-squids-tentacles.

04:44 If you’ve got a very complex system with subsets to it, this gives you a way of grouping logical calls together in the path to your API.

04:56 Until now, everyone can access every endpoint. That’s about to change. Next up, I’ll do authentication.

Become a Member to join the conversation.