Building a RESTful API with ASP.NET: A Visual Guide

So your boss wants you to build one of those RESTful APIs, eh?

Fortunately for you, you’ve got ASP.NET and its handy set of tools that are perfect for that kinda thing.

So – where do you begin?

An API can get pretty unruly if you aren’t careful with your design.

Nobody wants spaghetti. And nobody wants fat controllers that do way too much.

What if you could have a birds-eye visual of a proper API structure so you can dive right in and get it implemented clean, scalable, and ahead of schedule?

A Birds-Eye View

Below is a diagram showing the flow of an API request and response for adding a book to an imaginary online library. The request starts from an API client issuing an HTTP POST to /api/books .

The diagram components represent real ASP.NET classes that I’ll explain underneath the diagram.

An important note: This diagram shows the components of an actual RESTful API in ASP.NET for .NET Framework 4.7.1 but nearly all of it can be applied to .NET Core.

API Global Handlers & Filters

Handlers and filters are a kind of middleware that you can use to apply logic to the incoming request and the outgoing response. Handlers and filters can be applied either globally (the apply to every API request) or specific to a controller or method.

Log Request & Response Handler

In the diagram, you’ll notice the request first hits a logging handler. You can use a DelegatingHandler to peak into both the incoming and outgoing message so it’s perfect for logging.

Filters

Global action filters are a good candidate for authenticating and authorizing API clients. Before the message has a chance to get to the controller, make sure they are actually allowed to use your API, otherwise it’s wasted processing.

Here is a good link from Microsoft explaining filters more in depth:

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters

Controller & Endpoint-Specific Handlers & Filters

Once it is clear that this message is coming from an API authenticated and authorized client, it can move to more contextual processing.

I like to think of these filters like food prep. You’re making sure the request is in the best possible shape before it gets to the controller so that the controller can do the least amount of work possible. That’s how we keep it thin. The controller should receive a perfectly formed request object so it can do it’s job quickly and with very few calls.

In the diagram, the request must pass some additional authorization. Is this user/client actually allowed to add books or are they perhaps restricted to read-only?

Some validation is then applied, ensuring the book has proper fields. Are they trying to add the book to a bookshelf that doesn’t exist?

Controller Method Body

Once the request has been authorized and validated, it’s ready for the controller to do it’s work. In this case, we have a fully valid book object to be added to a database.

Pretty simple – we use our existing business layer to create a book domain object, save it, and return the resulting book back as the response.

Want more assistance?

This post could go on for days as we go deeper and deeper. If you’re looking for something specific, give me a shout on Twitter.