In the previous post where I was taking a look at Custom URIs in Azure Mobile Services I’d got to the point where I was defining server-side handlers in JavaScript for specific HTTP verbs.
For instance, I might have a service at http://whatever.azure-mobile.net/myService ( I don’t have this service by the way ) and I might want to accept actions like;
- GET /myService
- GET /myService/1
- POST /myService
- PATCH /myService/2
- DELETE /myService/3
In my previous post I didn’t know how to do this – that is, I didn’t know how I could enable Mobile Services such that I could add something like a resource identifier as the final part of the path and so I ended up using a scheme something like;
- GET /myService?id=1
- DELETE /myService?id=2
and so on.
Since that last post, I’ve been educated and I learned a little bit more by asking the Mobile Services team. I suspect that my ignorance largely comes from not having a real understanding of node.js and also of the express.js library that seems to underpin Mobile Services. Without that understanding of the surrounding context I feel I’m poking around in the dark a little when it comes to figuring out how to tackle things that aren’t immediately obvious.
Since asking the Mobile Services team, I’ve realised that the answer was already “out there” in the form of this blog post which covers similar ground to mine but comes from a more trusted source so you should definitely take a look at that and the section called “Routing” is the piece that I was missing (along with this link to the routing feature from express.js).
Even with that already “out there”, I wanted to play with this myself so I set up a service called whatever.azure-mobile.net and added a custom API to it called myService.
When you do that via the Azure management portal, some nice bit of code somewhere throws in a little template example for you which looks like this;
exports.post = function(request, response) { // Use "request.service" to access features of your mobile service, e.g.: // var tables = request.service.tables; // var push = request.service.push; response.send(200, "Hello World"); };
and what I hadn’t appreciated previously was that this is in some ways a shorthand way of using the register function from express.js as in a longer-hand version might be;
exports.register = function(api) { console.log("Hello"); api.get('*', function(request, response) { response.send(200, "Hello World"); }); };
Now, when I first set about trying to use that I crafted a request in Fiddler;
and I got a 404 until I realised that I needed to append the trailing slash – I’m unsure of exactly how that works;
but this does now mean that I can pick up additional paths from the URI and do something with them and there’s even some pattern matching built-in for me which is nice. For instance;
exports.register = function(app) { app.get('/:id', function(request, response) { response.send(200, "Getting record id " + request.params.id); }); app.get('*', function(request, response) { response.send(200, "Getting a bunch of data"); }); app.delete('/:id', function(request,response) { console.log("Deleting record " + request.params.id); response.send(204); }); };
and that’s the sort of thing that I was looking for in the original post – from trying this out empirically, it does seem to be important to add the more specific routes prior to the less specific routes. That seemed to make a difference to handling /myService/ versus /myService/1.