READ THIS FIRST

Update: 3-4-2016: If you're finding this blog and looking for information related to Azure Mobile Services, I'd strongly recommend checking out Azure Mobile Apps. Azure Mobile Apps is a new version (consider it a v2) of Azure's mobile backend support. All of the same features of Azure Mobile Services are there, with a lot of other very cool features to go along. You can read more about Azure Mobile Apps, and how to transition from Azure Mobile Services, here.

Last month at Microsoft’s Build conference in San Francisco, the General Availability of Mobile Services was announced.  In addition to that, several new features were released to enhance the server side functionality of Mobile Services.  Improvements to the client SDKs also came out to match.  Today I’m going to walk through these new features and how to use them.  Where appropriate, we’ll look at the client side code for iOS and Android.  The features we’ll be talking about are:

  • Custom APIs
  • Script Source Control
  • Shared Scripts
  • NPM Support

All of these have to do with server side scripting in some way.

Custom APIs

Prior to the release of custom APIs, the only endpoints your Mobile Service exposed were the REST APIs generated for each table you created.  Furthermore, each table operation was inherently tied to the SQL database table underneath it.  You didn’t (and still don’t) have to use that SQL database and could use the table operations almost like “virtual” endpoints.  However, with the release of custom APIs, you no longer need to do that.  Now, you can create a custom endpoint and assign different functionality to the different HTTP methods that it can receive (GET, POST, PUT, PATCH, DELETE).  Creating a custom API is a cinch once you have a Mobile Service created.  Go into the Windows Azure Portal and navigate into your Mobile Service.  Once there, select the API tab:

Custom API

 

Clicking on this takes you to a list of your custom APIs.  If you don’t already have one, click the CREATE A CUSTOM API link which will take you to this screen:

Create a custom API

Here we can name our custom API (I’ve named mine MyCustomAPI) and then choose permissions for each of the HTTP methods.  These permissions work the exact same way as the table scripts permissions do.  Your choices are:

  • Everyone – Anyone with the endpoint URL can access it.
  • Anybody with the Application Key – The Application Key must come across as a header to make it through.
  • Only Authenticated Users – A valid user ID and token must come through with the request.
  • Only Administrators – Only requests with the master key as a header will make it through.

Once you’ve named it and selected your permissions (you can always change these later if you want), you’ll be returned to the API list with your new API now showing up (after a few seconds of it being created).  Click on the name of the API to go into it.  The first thing you see is the scripts window with the following script:

Notice that this script is exporting functionality for the POST method by setting exports.post.  We’re doing the same for GET with exports.get.  In this one script we can specify functionality for all  5 of the HTTP methods.  Right now both methods will return an OK response (200) with the JSON message “Hello World!”.  Notice that the commented out code in the post code shows us how we can use the request.service module to access things like the tables and push modules (which are normally available without doing a special statement in our table scripts).  Just like our table scripts, we can put any matter of functionality we want here.  Let’s switch over to the client side now.

Calling custom APIs from iOS

When it comes to calling the Custom APIs from iOS, you have two different options: one that uses JSON as it’s request and response type and one that can handle any media type.  The first method looks like this:

Notice that this methods name is invokeAPI and as a first parameter takes in the name of the custom API.  The second parameter here is body which would be your JSON request object.  The next parameter is the HTTPMethod which in this case is GET.  Next we can optionally send in NSDictionaries containing any parameters or headers we want to apply to the request.  Finally, we define a completion handler which returns a result, a response, and an error.  The result parameter will be the actual JSON data you return from API method which in this case will be:

{ message = “Hello World!” }

The response is the actual NSHTTPURLResponse and is very useful for, among other things, checking the statusCode as well as any headers returned.  Lastly, the error will be filled if the API, or trying to call the API, lead to an error. 

The second method is nearly the exact same with the differences being the data sent across and the parameter type for result:

Note that the second parameter is now of type NSData and so is the type of the result object.  Since we are returning a NSData object, it’s up to us to decide how we want to interpret that.  So if we wanted to treat the data like a string, for example, we could pull that string out like this:

If we are using data of another sort, it’s up to us to convert it correctly.

Calling custom APIs from Android

Now let’s take a look at calling the same API from an Android app.  The Android SDK has considerably more options for invoking the API with 9 total method overrides for invokeAPI.  Let’s take a look at each one.  The first method just takes in the name of the API and a ApiJsonOperationCallback:

This method would be used if you want to pull back arbitrary JSON that isn’t casted to a type.  This method will automatically do a POST against your API.  Alternatively there are some more advanced methods that deal with using raw JSON:

  1. void invokeApi(String apiName, JsonElement body, ApiJsonOperationCallback callback)
  2. void invokeApi(String apiName, JsonElement body, String httpMethod, List<Pair<String, String>> parameters, ApiJsonOperationCallback callback)
  3. void invokeApi(String apiName, String httpMethod, List<Pair<String, String>> parameters, ApiJsonOperationCallback callback)

The first method here is the same as what we did above but allows us to specify an optional JSON body that will be sent as part of the request.  The next method is the same as the last but also allows us to specify which HTTP method to use (GET, POST, PUT, etc) as well as pass an optional list of parameters.  Finally the last method allows us to do the same thing with no body parameter.

Just like how there are raw JSON and typed method calls for table operations from Android, the same exists for the custom API.  The Android calls are:

  1. void invokeApi(String apiName, Class<E> clazz, ApiOperationCallback<E> callback)
  2. void invokeApi(String apiName, Object body, Class<E> clazz, ApiOperationCallback<E> callback)
  3. void invokeApi(String apiName, String httpMethod, List<Pair<String, String>> parameters, Class<E> clazz, ApiOperationCallback<E> callback)
  4. void invokeApi(String apiName, Object body, String httpMethod, List<Pair<String, String>> parameters, Class<E> clazz, ApiOperationCallback<E> callback)

Here the first method does a POST to the API where the data that is returned is of type E.  The second method does the same as the first but allows you to pass in an object to be serialized and sent over as the request body.  The third method allows us to specify which HTTP Method to use as well as a list of parameters to be passed over.  Finally, the fourth method allows us to do the same as the third but also specify an object for the request body.

Lastly, there is one method that can be used when you need explicit control over headers and the response:

  • void invokeApi(String apiName, Object body, String httpMethod,List<Pair<String, String>> requestHeaders, List<Pair<String, String>> parameters, ServiceFilterResponseCallback callback)

This method enables you to deal with the response however you want.

For much more on both the client and server side for custom API, take a look at this pair of blog posts from Carlos Figueira:

Script Source Control

Now that we’ve covered the new custom API endpoints, we can switch over to Script Source Control which will lead into the other new scripting features.  First, to enable Script Source Control, navigate in the portal to the Dashboard for your Mobile Service.  After a moment, a link will load up on the right side under quick glance:

set up script source

Click that link and wait while it gets thing set up.  After it completes, you’ll automatically be taken to the configure page where you’ll be able to see the GIT repo URL for your scripts:

Git Source URLs

Now you can copy that URL and clone your repo locally (using “git clone <repo">” once you’ve installed GIT).  You’ll want to use the GIT URL from that image as the DEPLOYMENT TRIGGER URL actually triggers a redeploy of your Mobile Service from your repository.  After you’ve cloned that directory on your local computer, you can look at the folder structure:

    • Root Folder
      • Service
        • api
          • mycustomapi.js
          • mycustomapi.json
          • readme.md
        • scheduler
          • readme.md
        • shared
          • readme.md
        • table
          • readme.md
          • TodoItem.json

The Service folder is meant to contain all of the scripts your Mobile Service uses.  Inside of that folder is an api folder which, as you can tell, contains the custom API we created above.  If you opened up the mycustomapi.js file you’d see the exact script we had above.  The accompanying mycustomapi.json file tracks the permissions for the different HTTP methods for that API.  Currently that file looks like this:

{"routes":
    {"*":
        {"get":{"permission":"application"},
         "post":{"permission":"application"},
          "put":{"permission":"application"},
           "patch":{"permission":"application"},
            "delete":{"permission":"application"}
        }
    }
}

Moving on to the scheduler folder, this will contain any scheduled job scripts you’ve created.  It’s good to point out that when you create a scheduled job, you’ll only see the JS file in this folder.  There isn’t a JSON file to control how often the job runs or anything like that.  Let’s skip over the shared folder for just a second and talk about the table folder.  This contains, as you might expect, all the scripts that correspond to our tables.  One thing that might seem weird is that we have a TodoItem table but there aren’t any script files for it, just the JSON file.  This is because if your scripts match the default (i.e. they only call request.execute()) they won’t show up as scripts.  Once you’ve changed a script to something other than the default, then it will show up in the following format:

tablename.operation.js

So if I changed the TodoItem insert script, I would have a todoitem.insert.js file in that folder.  Just like the api folder, we also have a JSON file for each table’s operations permissions. 

Each folder also contains a readme.md file that walks you through how the files in that folder are structured.

Shared Scripts

Let’s head back to the shared folder.  This folder allows you to create scripts whose functionality is then exposed to the other scripts in your Mobile Service.  So if you have the same logic that you want to use in multiple table / API / scheduler scripts, this is where you put them.  The readme.md details how to create such a script and we’ll walk through that example right now.  For this scenario, we’re going to generate a calculator script that will just add two numbers together.  So I’ll add a new file named calc.js to the shared folder and set it’s script to be:

exports.add = function(a, b) { return a + b; };

The exports.add means I’m making available a method named add to whoever uses my calc.js.  Now we can switch over to wherever we might want to use this script and do the following:

var calc = require('../shared/calc.js');
var result = calc.add(1,2);

So first we use require to get access to the shared script and then we can use the add method.  This is just a small sample but the possibilities here are endless as far as what you can do from inside the shared scripts.

Node Package Manager (NPM) Support

The last feature we’ll talk about today is the new support for NPM.  Node.js has a very rich ecosystem of Node modules which Node devs can use.  Prior to adding support for NPM, you were stuck with the few modules we exposed to the scripts (things like azure, mssql, push, request, etc).  Now, you can make use of the over 35,000 Node modules available from npmjs.org with ease.  In order to use these modules you should first make sure NPM is installed and then open up a terminal (or powershell) and navigate to the Service folder.  You can then install the module with:

npm install modulename

Then inside the script you want to reference the module, you’ll just use the following require string:

var mymod = require(‘modulename’);

And that’s all there is to using Node Modules with your Mobile Services

Summary

Today we looked at several new features of Mobile Services that are designed to give you even more power and flexibility when it comes to talking to your Mobile Service and performing server side functionality.  I’ve already had people comment to me on how happy they are with shared scripting so they’re able to reuse functionality across their other scripts and in time we’ll be adding even more features to make using Mobile Services not just easy, but a real delight. You can also take a look at many of these features being demonstrated in this article by watching this video.


Chris Risner