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.


Queries with Mediator and Command Patterns

Queries with Mediator and Command PatternsI recently got a really great comment from my post on using Query Objects instead of Repositories.  Although that blog post is now 2 years old, I still use the same concepts today in my applications.

What I thought may be relevant is to elaborate more on why and when I use the mediator and command pattern for the query side.

It may seem obvious on the command side, but not really needed on the query side.

Here a portion of the comment from Chris:

I’m struggling a bit to see the killer reason for using Query objects over repository. I can see the benefits of CQS but it’s this command pattern type implementation of the Q part I struggle with. I can see for Commands (mutators) the benefits of having separate handlers as you can use decorator pattern to wrap them with additional functionality e.g. Transaction, Audit etc.

However for queries I’m struggling to see why you wouldn’t just use a normal repository. Essentially your IQuery object defined what would be a method signature in the repository and the handler defines the implementation of the method. However at some point you have to compose the IQuery class to it’s handler either using a dependency injection framework or Mediator pattern as in your following blog.

Query Objects

The primary place I use query objects (mediator + command pattern) is when I want to be decoupled from an integration boundary.  Often times this is between my application and the web framework I’m using.

I view my query objects as my public API.

Which means I usually want to create a pipeline for those queries.  I will use a request pipeline for handling things such as authorization, validation and logging in the query pipeline.

Since this is the same implementation I use on the command side, it’s easy to use with library like MediatR which handles both commands and queries as a “Request”.

Repositories

I still use repositories, but just very differently than I did before.  Since my query objects are my public API, my repositories are generally only used internally within a the core of a given application (or bounded context).

My repositories are usually pretty narrow and also handle things like caching.

CQRS

There are many ways to implement the separation between reads and rights.  I’ve failed at making this point clear in many of my prior posts.

I’ve had a few encounters recently that make me feel like there’s still a lot of misconceptions about what people think CQRS is.  I’ll keep posting quote from Greg Young.

CQRS is simply the creation of two objects where there was previously only one.

The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

That’s all it is folks.  Not really that interesting.  What’s interesting are all the possibilities because of this simple idea.

How you implement that is up to you.

One of the ways I’ve been implementing this is with the Mediator + Command Patterns.  It’s not the only way!

Comments

How are you implementing the query side?  Always enjoy hear your feedback, commands and questions.  Please let me know on twitter or in the comments.


 

Developing Features not Layers

Developing and thinking about features not layers is something I’ve moved towards over the last several years.

I’ve mentioned it in several blog posts and I don’t think I ever explicitly created a post about it.

CQRS

The real enabler has been CQRS.  For those unfamiliar with CQRS or if you think it’s complicated, let me share a quote from Greg Young:

CQRS is simply the creation of two objects where there was previously only one.

The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

That’s it.  It’s nothing more complicated than that.

I think where the confusion lies is a lot of articles, blog posts, etc where the content describes much more than CQRS.

CQRS is not event sourcing.

CQRS is not domain driven design.

CQRS does not mean multiple data stores.

CQRS does not mean using a service bus.

CQRS does mean having eventual consistency.

CQRS is simply the creation of two objects where there was previously only one.

Features vs Layers

For me a feature in the technical sense is a command or a query.  It could also be a combination of a few put together.

I often have commands and queries dictate on their own how they are layered inside.

This means that an individual command decides how it may do data access.  It may not be a shared concern between another command.

For comparison, here’s is how I visualize the difference.

Layered

Layered

In the layered approach, we separate and organize our code by technical concerns.  Authentication, Business Logic Layer (BLL) and Data Access Layer (DAL) are all contained.  Once layer invokes the next.

CQRS

Features not Layers

The difference in our CQRS approach is that our Commands and Queries contain the layers of technical concerns within them.  We don’t have layers spanning over the entire application.

This has some pretty profound implications in terms of being able to make different decisions in smaller units.

As well the biggest distinction is we can start thinking, developing and organize our code by business concerns rather than technical concern.

Organizing by Feature

If you want to see how this works in practice, I’ve blogged about writing your code this way.  Most of my sample code uses the MediatR library for handling things like Commands and Queries.

I recommend checking out my Fat Controller CQRS Diet: Vertical Slices post which demonstrates how to do this in ASP.NET MVC Core.

Testing

One aspect that took longer to come around was testing in the same manner.

Meaning, I start writing tests and thinking about them around my features rather than layers within a feature.

My new few series of posts will be around testing features / vertical slices.

I love hearing your comments, questions and recommendations as it usually leads me down to other blog posts.  Please post a comments or on Twitter.