Page 12 - MSDN Magazine, February 2018
P. 12
Figure 3 The HTTP Trigger Integration Settings
Now it’s time to return to the function code, which you can do by clicking on the GetUserScores Function. This will display the run.csx code, which is still in its default state.
Writing the Function Code
to Respond to the Integrations
Consider the SQL for the integration input, which retrieves four columns: score, worthit, deviceName and dateTime. You could create a class to match each type (as I did in the StoreScores Func- tion of the previous article), or just tell the function that the input Function will be passing in a dynamic type. That’s what my code does. Figure 4 shows the entire function in the run.csx file.
In its signature, the Run method acknowledges that the first parameter is a string named userId that comes in via the route specified in the trigger settings. After the userId, the parameters expect the HttpRequestMessage (req) and then the IEnumerable containing the documents. Behind the scenes, the Function will take the userId that came in through the trigger’s route and pass it on to the input integration, which will execute the query (using the userId) and populate the documents variable with the query results. After this, the Function will finally call the Run method’s logic that I’ve written.
The code first checks that the documents were, indeed, passed in to the method. I output a message to my log with the count of those documents and then simply pass them back in the HTTP response. If I weren’t doing any checks and balances, the method
would still work in this simpler format:
public static HttpResponseMessage Run(string userId, HttpRequestMessage req, IEnumerable<dynamic> documents)
{
return req.CreateResponse(documents);
}
In other words, for this entire Function to receive a userID and return that user’s top five scores from the database takes just a sin- gle line of code that’s no more than “send back the documents that came in from the input integration.”
The Azure Function’s integrations have really done all the work for me. I am truly impressed.
I can test this Function in the portal or in a tool like Fiddler or Postman. Testing from a browser won’t work with the Function in its current state because the Function is returning dynamic objects and a browser can’t send the necessary Accept header. Alternatively, you could define a class that matches the query results and use that class
instead of a dynamic object. But as it is, the Function will work correctly when calling it from Fiddler, Postman or your APIs, such as the one you’ll eventually use from the UWP app.
The Get Function URL link tells me I can call https://cookie- binge.azurewebsites.net/api/Get- UserScores/{userId}. If the Function weren’t anonymous, then I’d have to pass some credentials in, but I’m intentionally keeping it simple here.
With my userId, 54321, in the placeholder, the URL looks like this: https://cookiebinge.azurewebsites.net/api/GetUserScores/54321.
The Azure function’s integrations have really done all the work for me. I am truly impressed.
This URL returns five JSON-formatted documents with the schema shaped by the query. Here’s one of the documents returned in the HTTP response, showing that when I played on my Xbox, I scarfed down 18 cookies, but wasn’t so happy about my binge that day.
{
}
"score": 18,
"worthit": false,
"deviceName": "XBox", "dateTime": "2017-11-05T15:26:00"
A Shortcut for Creating Another
Fully Integrated Azure Function
Now that I have the first Function set up, it’s time to create the sec- ond, which will retrieve the top five scores for all players around the globe. Rather than go through all of the settings forms again, though, I’m going to take a short cut. The settings for all of the integrations of an Azure Function are stored in the function.json file, which you can open up in the portal from the View Files pane. Figure 5 shows the function.json for the GetUserScores Function. The bindings section wraps all of the integration settings.
Figure 4 The Run Method of the GetUserScores Function
using System.Net;
public static HttpResponseMessage Run(string userId,
HttpRequestMessage req, IEnumerable<dynamic> documents, TraceWriter log)
{
if (documents != null) {
log.Info($"Document Count: {documents.Count()}");
return req.CreateResponse(HttpStatusCode.OK,documents); }
else {
return req.CreateResponse(HttpStatusCode.NotFound); }
}
8 msdn magazine
Data Points