Self Descriptive HTTP API in ASP.NET Core: Object as Resource

In my opening post I went over some of the issues I encountered when initially developing an HTTP API.  In this post I’m going to cover some of those pain points and what I think the solution was.

Objects

The first pain point revolves around the idea of your HTTP API returning objects.  Meaning you serialize an object to JSON and return to the client.

This seems pretty typical.   Almost every example you find in regards to Web API describes this behavior.

Here’s an example of what this looks like:

We’re doing nothing more than fetching a record out of our repository/database and serializing it down the to the client.

On the flip side, all of our endpoints for mutating state of our system take the same object back.

Object as Resource

There was a great and short blog post by Alex Moore last year.

You’ve doubtless seen the OAR pattern out in the wild. I’d define its constraints this way: 1. a resource maps 1:1(-ish) to an object in your server’s application logic, 2. uris and http methods are given conventions mapping to CRUD operations

These are what most examples I find describe.  If you ever used OData with Entity Framework, it’s another great example of OAR.

Model Changes

The first obvious issue with this is your exposing your internal data structure to your consuming clients.

If you do not have ownership over the clients, then making any breaking change to the structure TodoItem is going to be pretty difficult.

This is really problematic when your internal models are still evolving.

DTO

The obvious answer is to create DTO (Data Transfer Objects) as the essentially a contract to your consuming clients.  Meaning you will create a separate object that will be serialized and return to clients rather than your database entity.

This is generally a recommended approach that I use.  This is where a library like AutoMapper shines.

Representation

But we need to take this a step further.  The idea of returning serialized DTO that still are in a 1:1-ish with some underlying data entity only provides our clients a single piece of information.

Often times in order for the client to perform a given action, they generally need related data.

An example, maybe our Todo application had the ability to create different categories so we could break up and categorize our items.  If we wanted to edit our TodoItem to specify a Category, we would need to pass it the CategoryId.

How exactly do we get the list of categories from the client?  Would the client be required to call another endpoint to them?

Why not return them in our DTO?

We would be doing this already if you were creating an MVC application returning a rendered HTML to the client/browser.

Your edit screen would contain a <select> list of all the categories in your edit <form>.

Messages

If you start thinking about sending down messages to the client rather than objects, you can open up to the idea of your messages being a much more rich representation.  This representation could contain referential data, actions the client could preform or other places the client could navigate your HTTP API.

Last year, I wrote a blog post about your Resource Model not being your Data Model after I seen a great tweet by Mike Amundsen.

Next

In my next post I’m going to look at how we build HTML web applications and what we can learn and use to develop our HTTP APIs.  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.


Paging DocumentDB Query Results from .NET

Paging DocumentDB Query Results from .NETI received a comment on my DocumentDB Transactions from .NET post from Onur:

The thing I don’t like about documentdb is that it doesn’t support aggregations nor paging.

This was actually some pretty good timing of this comment as I just ran into a situation of a side project that required to page through  a result set.

Skip & Take

It does not appear that DocumentDB supports (yet) SKIP and TAKE, which you would expect to use in order to do paging.  Because of this, you can’t implement all the same functionality you might expect.

But there is a a way to limit the number of records returned in a query and subsequently having the next query return the records were the previous query left off.  This means you can basically continue through your result set.

Continuations

DocumentDB has the concept of a continuationToken which is returned from a query which limits the number of records to return.  When using the CreateDocumentQuery<T> from the .NET SDK, you can specify an additional parameter for FeedOptions.

FeedOptions

Here’s an example of using FeedOptions to limit the number of results:

RequestContinuation

FeedOptions also property for specifying the RequestContinuation.  If you original query had a MaxItemCount and your query result exceeds the specified count, then your results will contain a ResponseContinuation property.

Combine these two to basically do forward paging.  Here is an xUnit test to outline:

 

 

Demo Source Code

I’ve put together a small .NET Core sample with an XUnit test from above. All the source code for this series is available on GitHub.

Are you using DocumentDB? I’d love to hear your experiences so far along. Let me know on twitter or in the comments.


 

DocumentDB Transactions from .NET

DocumentDB Transactions from .NETI received a comment to my Optimistic Concurrency in DocumentDB  a couple weeks ago from Jerry Goyal:

Can we somehow handle the concurrency among multiple documents (transactions)?

Since ETags are defined on each document, you must build your concurrency around them.  However, this made me start to wonder how to update multiple documents at the same time using their respective ETags.  Meaning you would want both documents to update together only if both of their ETags were current.  If one was valid and the other was out of date, none of the documents would update.

Transactions

It’s pretty obvious that I’m looking for transactions within DocumentDB.

DocumentDB supports language-integrated transactions via JavaScript stored procedures and triggers. All database operations inside scripts are executed under snapshot isolation scoped to the collection if it is a single-partition collection, or documents with the same partition key value within a collection, if the collection is partitioned.

There is no client transaction scope you can use with the .NET SDK.   Meaning from the client (.NET) you cannot create a transaction scope.  It has to be done on the DocumentDB server via  stored procedure or trigger.

DocumentDB Emulator

There are several ways you can create a stored procedure.  One of which is via the DocumentDB Emulator web UI.

You can create a store procedure under any given collection.

You can also create stored procedures via the .NET SDK using the CreateStoredProcedureAsync.  However for this demo, I’m going to be creating it via the emulator.

Stored Procedure

For demo purposes I wanted a way to do a bulk insert.  If any of the customers failed to be added to the collection, due to the Name being falsey, I don’t want any to be created.

Here is the stored procedure I created called sp_bulkinsert.  Notice the getContext() method which is available to.  Check out the JavaScript docs for more on the Context/Request/Response.

Client

Here are a couple tests using the .NET SDK which call the stored procedure passing in an array of new customers.

The first test passes returning the number of created customer documents.  The second test fails because the customer name is empty/blank.

 

Demo Source Code

I’ve put together a small .NET Core sample with an XUnit test from above. All the source code for this series is available on GitHub.

Are you using DocumentDB? I’d love to hear your experiences so far along. Let me know on twitter or in the comments.