Categories
Javascript Python

Django REST Framework & AngularJS $resource – Trailing Slash Problem

If you use ngResource ($resource) from AngularJS, you probably have already noticed that AngularJS removes the trailing slash from an URL. Django, on the other hand by default has “APPEND_SLASH” turned on. So when you request:

http://example.com/api/object

Django redirects you to:

http://example.com/api/object/

Yes, Django adds an extra slash to the URL. Django REST framework also follows this scheme. Every api end point has a trailing slash.

Angular, not having any trailing slash will always request the first URL above and get redirected to the second one. Apart from the cost of one extra http request, this is fine. The pain appears when we want to make POST request. Django can’t redirect POST requests and won’t accept POST data on the URL without a slash at the end. Damn, Our AngularJS app breaks because it can’t make request to the URL Django expects!

This is a very annoying and known bug with an open issue on their Github for quite sometimes. Since the latest version doesn’t yet have it fixed, I was stuck. Then I noticed somewhere that Django REST Framework responds to this particular bug allowing an extra parameter to “DefaultRouter” to create API endpoints without any trailing slash. Just do this –

It will make sure that the API urls don’t have any slash at the end and play nice with Angular. But we’re not done yet, Django will still try to redirect requests appending a slash. Let’s fix this by adding this to the main settings.py:

Now, we should be able to make REST calls using AngularJS and $resource with sanity! 🙂

Categories
Javascript

Django REST Framework, AngularJS and SessionAuthentication

Here’s the scenario, I am working on an application that uses Django REST Framework in the backend. On the front end I use AngularJS with ngResource. The application is expected to have a web front end and mobile applications in the future. So I chose both BasicAuthentication and SessionAuthentication as default authentication options. BasicAuthentication uses the basic HTTP Auth to verify the user and is suitable for mobile devices. And SessionAuthentication uses the default Django session. Since I have a web front end, SessionAuth comes very handy – I don’t need to send auth data on every request if the user is logged in already.

This works excellent for GET or HEAD requests but things get rough when you need to make a POST, PUT or DELETE request. SessionAuthentication depends on the CSRF token mechanism built into Django. Django requires a special header to be sent with the csrf token. Details are on the Django docs – https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax.

Getting the cookie and parsing the csrf token part is rather simple. I ported the jQuery version to a generic JavaScript version just by replacing jQuery.trim() with String.prototype.trim() –

Now, ngResource or $resource isn’t very customizable compared to the $http component and most people suggested me to use the latter. Just when I was about to lose hope and planning to rewrite my own wrappers around $http, I just came to realize that $resource is also based on $http. If I can change the global $http config to push the header, $resource will also use the same header. So, I configured things like this –

And finally it works! 😀 Now, every POST request made using $http will have that extra header. But I don’t mind since my application is probably not going to make POST requests to any alien servers 🙂

Categories
Javascript

REST access in AngularJS using ngResource

This will be a short and quick walk through on how to make REST API calls using AngularJS. We shall use ngResource to aid us.

Loading ngResource

If we want to use the ngResource module, we have to make sure it’s being loaded separately along with angular. We need to have something like –

Creating a Module and Resource Objects (Mapping)

Now, we shall create a module named “apiService” to keep our REST stuff separate from our main application logic.

Then we shall map REST api calls to our Angular resource objects. Here we create a Booking resource object and the factory method allows us to do that –

Here we create a new resource object which maps to the API url – “/api/booking” with an optional parameter “Id”. Then we define a set of default parameters to be used, here we instruct to extract the value of “:Id” if “Id” is present in the set of params passed.

The above resource object can make these requests:

GET /api/booking/ — Gets all booking
GET /api/booking/1 — Gets the booking with ID 1
POST /api/booking/ — Creates a new booking
PUT /api/booking/1 — Update booking ID 1
DELETE /api/booking/1 — Delete booking ID 1

Besides the basic methods, we have also added a custom method named “reviews” which would add “reviews_only=true” to make a GET query and return the result as an array. This is helpful to deal with custom queries.

Making Rest Calls

Here comes the fun, how do we use the Booking object to make the different calls?

When making the calls, we need to remember that the first parameter contains the actual data. These data will be used as the parameters of the API. This can be appended like query strings or POSTed. The API will use these data to filter the response. Where as the second parameter overrides the default parameters for the resource definition. It is used by Angular to decide how to make the REST call. In our case, we used – “/api/booking/:Id” as our api entry point and then defined default parameters as – {Id: “@Id” }. So here, the second parameter will help angular decide which URL (by providing the value for Id) to make the request to. We didn’t need to pass any data but we did need to pass the ID in some methods. This is why most of the methods were passed an empty object as the first parameter.

This should explain things a bit more –

Each of these methods allow a callback function to be executed when there is a response from server.

Simple, isn’t it?