Jeremy Likness
Jeremy Likness
Empowering developers to be their best.
📅 Dec 1, 2017 🕘 3 min read 💬 576 words

Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 1: Content Negotiation

Leveraging cross-platform C# and .NET to build consumer-friendly Web APIs.

Part of the series: Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0

I recently presented a full day workshop on Web API design at PASS Summit 2017. If I was a betting man, I’d gamble that I was invited as the result of my work on the Web API Design jump start that I did for Microsoft Virtual Academy (MVA). I built the workshop from the ground up and presented to about 40 attendees in Seattle. I chose to leverage .NET Core 2.0 for implementation examples because it is cross-platform and I can demo entirely in the cross-platform Visual Studio Code.

Web API Session

You can access the decks for the talk and the code for the examples in the GitHub repository.

 JeremyLikness/PASS-2017

Every example leveraged a simple set of APIs for an in-memory “to do” application. The “starter project” is named Src-TodoApi (it can be accessed here.) If you’re interested in learning about some of the more conceptual topics like idempotency, you can read the deck; this post covers several design ideas that are implemented in code.

Content Negotiation

Properly implemented REST end points may support content negotiation. The purpose is to provide a framework for determining the media format of the response. The most common example is to forego the ubiquitous JavaScript Object Notation (JSON) format and instead support the more seasoned Extensible Markup Language (XML). That means getting something like this:

<user id="1">
   <name>Jeremy Likness</name>
   <blog>https://blog.jeremylikness.com/</blog>
</user>

Instead of the more popular version that looks like this:

{
  "user": {
    "id": 1,
    "name": "Jeremy Likness",
    "blog": "https://blog.jeremylikness.com"
  }
}

There are several ways to implement content negotiation. One is for the server to return a set of links for a request, each representing a different media type. A far more common approach is for the client to provide a list of acceptable formats in the request, leveraging the Accept header. It is then up to the server to detect which format is acceptable and format the result accordingly.

.NET Core 2.0 Web API supports JSON out of the box. To test this, use a tool like PostMan to GET a “to do” item. In the request headers, add:

Accept: text/xml

Despite the request for angle brackets, the response comes back with curly braces.

Non-negotiation

To properly support XML, first add the NuGet package:

dotnet add package Microsoft.AspNetCore.Mvc.Formatters.Xml

Then configure the MVC engine to “respect mah authori-tah” and match the media requests with the formatter implementations.

services.AddMvc(options =>
{
    options.RespectBrowserAcceptHeader = true;
    options.FormatterMappings.SetMediaTypeMappingForFormat(
        "xml", MediaTypeHeaderValue.Parse("text/xml"));
    options.FormatterMappings.SetMediaTypeMappingForFormat(
        "json", MediaTypeHeaderValue.Parse("application/json"));
})
.AddXmlSerializerFormatters();

Build and run the project now, and you’ll see your request for text/xml is now honored.

XML

You don’t have to stick with what’s in the box, either. You can create your own formatters so that “anyway you want it, that’s the way you need it …” I’m getting a little choked up right now. Is my age showing? If the formatter is text-based you can inherit from TextOutputFormatter and build your own parser. This one turns “to do” items into a comma-separated values.

Don’t forget to match the formatter to the media type and add an instance to the list of available formatters.

Future negotiations should go quite well!

Command Separated Values

If you’re lazy and didn’t want to follow along, the finished project is available here. I also made this short video to show you how to get started:

This is the first article in a multi-part series. For easy navigation:

  1. Intro and Content Negotiation (“you are here”)
  2. HATEOAS
  3. Exceptions
  4. Concurrency
  5. Security
  6. Bonus (because I said it would be five): Swagger

Regards,

Jeremy Likness

Do you have an idea or suggestion for a blog post? Submit it here!
comments powered by Disqus

Part of the series: Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0

  1. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 1: Content Negotiation
  2. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 2: HATEOAS
  3. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 3: Exceptions
  4. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 4: Optimistic Concurrency
  5. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 5: Security
  6. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Bonus: Swagger