Building a Self Descriptive HTTP API in ASP.NET Core

Self Descriptive HTTP APIWe have all been doing “web services” forever.  My first introduction was in the late 90’s with XML-RPC and WDDX.  Followed up soon after with SOAP.  Good times.  Oh and remember WS-*.  Don’t remind me.

Why?

Over the last couple years, I’ve really taken an interest in HTTP APIs.

I’ve been meaning to post about my experiences developing an HTTP APIs.  It’s been an interesting last couple of years and I think there is quiet a bit to share.

Issues

I can only speak from my experiences and give some of the context about my situations.  Hopefully you can relate and translate it to your own projects and make a determination if what I struggled with is beneficial in your context.

There were four major pain points that I ran into developing our HTTP API and Clients.

  • Unable to change internal data structures that got exposed/serialized to Clients
  • Unable to change endpoint paths/routes
  • Endpoint documentation (incoming and outgoing payloads)
  • Workflow logic living on the client

HTTP APIs

Sometimes all you need is to do CRUD.  Sometimes that’s the last thing you should be doing.

Most examples and getting started tutorials usually demonstrate exposing your database structure and provide GET/POST/PUT/DELETE as away of performing CRUD.

You basically end up with HTTP endpoints that are a 1:1 mapping with a database entities.

This also makes it incredibly hard to change your API.

Go beyond serializing a database row into JSON

I’ve realized that developing an HTTP API is not much different than developing a regular HTML Website.

I started developing my HTTP APIs like I would if I were creating a static HTML or server side rendered HTML web application.  This means bringing the concepts we’ve been using for ages with HTTP and HTML such as links and forms.

(Un)Surprisingly, this lead to several benefits.  First, our API clients could consume our API with ease.  Second, they became dumb.  Workflow or business logic stayed on the server and didn’t leak to the client.

Series

This series of posts is going to cover some misconceptions I had in regards to HTTP APIs and REST.

Producing an HTTP API using Hypermedia and various media types.

Consuming an HTTP API that uses Hypermedia.

How you can use CQRS and Hypermedia together.

Similar to my Fat Controller CQRS Diet series, I’m going to convert an existing web application.   Currently I’m thinking of using the MVC Music Store again.  If anyone has any other suggestions or recommendations about this series, or the sample project to convert, please leave comment or let me know on twitter.

  1. Building a Self Descriptive HTTP API in ASP.NET Core
  2. Object as Resource
  3. Hypermedia
  4. Siren
  5. HATEOAS
  6. Hypermedia Clients


Environment Variables in ASP.NET Core

In my last post, I covered how to handle sensitive configuration data by using User Secrets while working in development or on your local machine.  The next step is how to use environment variables in ASP.NET Core once you deploy to production (eg Azure App Service)?

If you have any questions, please follow me on Twitter.

 

IHostingEnvironment

In your ASP.NET Core Startup class, the ctor has a IHostingEnvironment parameter.  One of the properties on it is the EnvironmentName.  Along with this are a few extension methods such as IsDevelopment(), IsStaging(), IsProduction().

In the sample below, you can see if the environment is development, then I’m adding the User Secrets to the ConfigurationBuilder.

What IHostingEnvironent.IsDevelopment() ultimately does is checks to see if the IHostingEnvironment.EnvironmentName is equals to Development.

ASPNETCORE_ENVIRONMENT

How did IHostingEnvironment.EnvironmentName get set to Development?

If you are using Visual Studio you can access this in the in the project properties.

If you are outside of Visual Studio, you can manage it by editing the launchSettings.json.  This is what a sample looks like.

Environment Variables

You can also add additional environment variables that will be loaded when ConfigurationBuilder.AddEnvironmentVariables() is called in Startup.

In my above example, only under development are user secrets loaded.  This is done after environemnt variables are loaded.  This means that the user secrets override any environment variables I’ve set.

Azure AppService

Once you are ready to deploy to azure, you may want to set your environment as well as other environment variables that you need which will be used instead of user secrets.  You can do this in your App Service under Application Settings.

 

 

 

Always enjoy hear your feedback.  Please let me know on twitter or in the comments.

Sensitive Configuration Data in ASP.NET Core

While working on my new side-project in ASP.NET Core, I was at the point where I needed to start storing sensitive configuration data.

Things like my DocumentDB Auth Key, Google OAuth ClientId & Secret, Twilio Auth Token, etc.

Depending on your context you may not want to be storing these types of application settings in configuration files that are committed to source control.

As you would expect, my local environment for development and once I deploy to Azure have completely different configurations.

So how do you change the configuration from local to production?

If you are used to using appSettings from the app.config and web.config, you may have been going down the road of transforming and replacing values with tools like SlowCheetah or through Octopus Deploy.

With ASP.NET Configurations, there’s a new way to do this.

If you have any questions, please follow me on Twitter.

Configuration

ASP.NET Core has a ConfigurationBuilder that enables you to load application settings from various places.  If you’ve loaded up a brand new ASP.NET Core app, you’re Startup looks something like this.

You have a new appsettings.json file you can use as well as an optional appsettings for each different environment.

I could use the appsettings.Development.json for local development, however as mentioned i want to keep sensitive data out of this file.

For this, I’ve now been using User Secrets.

User Secrets

ASP.NET Core adds a new way to store your sensitive data with User Secrets.

User Secrets are simply a plain text json file that are stored in your systems user profile directory.  Meaning the file is stored outside of your project directory.

There are a couple ways to manage your user secrets, first you need to add Microsoft.Extensions.SecretManager.Tools in the tools section of your project.json.

I’m unaware of how this translates to the new .csproj format.

If you are using the dotnet CLI, then you should now be able to run dotnet user-secrets --version

Next in your project.json you want to add a “userSecretsId” property in the root.  The value can be anything you want but should probably keep it unique so it doesn’t collide with another user secrets you create for any other project.

In order to load the secrets file, you need to first add Microsoft.Extensions.Configuration.UserSecrets package in your project.json

As mentioned, since I only use user secrets for local development, we can now load the secrets using the ConfigurationBuilder in our Startup

Visual Studio

If you are using Visual Studio, you can edit your user secrets file by accessing it in the context menu of your project in the solution explorer.

CLI

If you are using the dotnet CLI then you can call dotnet user-secrets [options] [command] to clear, list, remove and set secrets.

Example

Simple example would be wanting to store the connection string to a database.

 dotnet user-secrets set ConnStr "User ID=Derek;Password=CodeOpinion;"

Now within our code we can access the connection string after we built our configuration from the ConfigurationBuilder.

Production

Next post I’ll take a look at how you can use Environment Variables and specifically how to set them when deploying as an App Service within Azure.

Always enjoy hear your feedback.  Please let me know on twitter or in the comments.