XF vs PWA: Setting Up the API

Setting Up the API

In this post, I thought we would go over the API: the API will be able to be shared between both the Xamarin Forms app and the PWA. To get access to the API, you have to apply to the Translink Authority and get an API key. Of course, you shouldn’t share that API key with anyone, and that can be pretty difficult to achieve when you have a mobile app that must send it to the provider.

One way you can do it is to hide the key in your app somehow or encrypt it. But if you encrypt it, you are going to have to unencrypt it as well and that means hiding a different key. For this app, I am just going to proxy the provider API with my own API and that way, I won’t have to store the Translink Authority API in my local app. If this was a serious app, I would consider using my own keys and/or looking at user info in my app to guard against mis use. It is much easier to revoke my own keys than it is to have to go back to the Translink Authority for a new key in the event of misuse.

Storing the Key

I am just going to store the key in my appsettings.json file for simplicity. Your appsettings.json is stored in the root of the web api project. It looks like the following:

{
"Logging": {
"includeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
},
"mySecrets": {
"translinkKey": "xxxxxxxxxxxxxxxxxx"
}
}

To get access to the settings, we have to do some work in the Startup class. I changed the Configuration property to be an instance of IConfigurationRoot interface. To create that, I changed the constructor object to create it.

public class Startup
{
    public IConfigurationRoot Configuration { get; }
    private IHostingEnvironment _hostingEnvironment = null;

    public Startup(IHostingEnvironment env)
    {
        _hostingEnvironment = env;
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSingleton<IConfigurationRoot>(Configuration);

        // rest of code
    }
}

To access the settings in your controller class, you need to have the IConfigurationRoot object injected into your controller through the constructor.

[Route("api/bus")]
public class BusController : Controller
{
    private IConfigurationRoot _configuration = null;
    private string _apiKey = null;

    public BusController(IConfigurationRoot configuration)
    {
        _configuration = configuration;

        var section = configuration.GetSection("secrets");
        _apiKey = setion.GetValue<string>("translinkKey");
    }

    // controller actions go here
}

Now with the API key the web app can make calls to the Translinke API directly.

If you feel like checking out some of the code, you can find it here.

JSON to C#

Do you ever get tired of translating JSON to the equivalent C# shape for your app? I do. One of the tools that I like to use is quicktype. It is a web app that will allow you to paste in some JSON and it will generate the C# classes for you. That’s a pretty good start.

But it gets better than that. If you are like most, and you use NewtonSoft Json.NET (if you don’t, you should check it out), it will decorate the properties it generates with the [JsonProperty] attributes with the property name from JSON while the C# property has the standard casing.

It also has features for handling things like enums, maps, lists or arrays among others.

https://app.quicktype.io/#l=cs&r=json2csharp

Check it out, I love it.