Web API: Resource Model isn’t your Data Model

Web API: Resource Model isn't your Data ModelI was recently reminded of some troubles I had awhile ago which were caused by exposing my data model. This tweet by Mike Amundsen brought up some thoughts that I had yet to share, and why I now suggest that you don’t expose your data model.

OData

A good illustration of the above is with how you see most examples of using OData with .NET and Entity Framework.

The problem lies that the model being exposed via Web API/OData is your backing Entity Framework data model.

In this case, your Data Model (Table) is your Object Model (C#) is your Resource Model (OData).

The Problem

There are a couple issues with exposing your data model.

The first one is pretty apparent the moment you need to start changing your data model.

Having the consumers of your API being loosely coupled poses some challenges when you change the backing model.

If you are creating a public API, you have no control over the clients.  And if the app is internal and you do control the clients, it can still be a nightmare updating them to work with your new data model.

Versioning

You could make the argument that you need to version if you are going to change your data model.  There are a numerous ways you can attempt to version your API.

I’d recommend having a listen to Sebastien Lambla (SerialSeb) talk on “Versions are Evil How to do Without in your API“.

Resources not Objects

I think of resources in an Web API as being about features or capabilities rather than objects.

For example, say this was our product data model:

When thinking about a product as a resource, I would likely want to more data.  I tend to drive a resource by the consumer.

Our backing model likely has other related data.  For example, a product may have a “AvailableToPromise” field which indicates available quantities.

So now our Product resource is starting to diverge from our data model.

CQRS

I tend to follow a CQRS style approach to Web API’s. For me, commands and queries are resources.

In regards to a Product, we likely have the ability to do some sort of Inventory Adjustment (command).  I would expose the Inventory Adjustment command as an endpoint and provide that endpoint with our Product Resource.

This way the consumer can start navigating and sees other available resources.

Comments

Web API’s and hypermedia are something I’m trying to understand more of and how I can create better Web API’s.

Let me know if you have any comments related to Web API’s either in comments or on twitter.