.net, C# tip, Clean Code, Visual Studio

Creating a RESTful Web API template in .NET Core 1.1 – Part #1: Returning HTTP Codes

I’ve created RESTful APIs with the .NET framework and WebAPI before, but nothing commercial with .NET Core yet. .NET Core has been out for a little while now – version 1.1 was released at Connect(); //2016 – I’ve heard that some customers now are willing to experiment with this to achieve some of the potential performance and stability gains.

To prepare for new customer requests, I’ve been experimenting with creating a simple RESTful API with .NET Core to see how different it is to the alternative version with the regular .NET Framework…and I’ve found that it’s really pretty different.

I’ve already written about some of the challenges in upgrading from .NET Core 1.0 to 1.1 when creating a new project – this post is about how to start with the default template for Web API projects, and transform it into something that is more like a useful project to host RESTful microservices.

This first post in the series is about turning the default project into a good HTTP citizen and return HTTP status codes.

When I create a new WebAPI project using .NET Core 1.1 from the default Visual Studio template, a number of files are created in the project. The more interesting one is the “ValuesController” – this holds the standard verbs associated with RESTful services, GET, POST, PUT and DELETE. I’ve pasted the default code created below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1""value2" };
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
 
        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

However, one of the things I don’t like about this which would be very easy to change is the return type of each verb. A good RESTful service should return HTTP status codes describing the result of the action – typically 200 codes for success:

  • 200 – Request is Ok;
  • 201 – Resource created successfully;
  • 202 – Update accepted and will be processed (although may be rejected);
  • 204 – Request processed and there is no content to return.

Additionally, responses to RESTful actions will sometimes contain information:

  • 200 – OK – if the action is GET, the response will contain an object (or list of objects) which were requested.
  • 201 – Created – the response will contain the object which was created, and also the unique URI required to get that object.
  • 202 – Accepted – the response will contain the object for which an update was requested.
  • 204 – No content to return – this could be returned as a result of a delete request, where it would make no sense to return an object (as it theoretically no longer exists).

    As a brief aside, some writers disagree that the Delete request should return no content – for a HATEOAS application, I can see why returning an empty response is not helpful.

I think the default ValuesController would be more useful if it implemented a pattern of returning responses with correctly configured HTTP status codes, and I think the first step towards this would be to use the default code below for the ValueController (which – as a default template – obviously does nothing useful yet).

using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new string[] { "value1""value2" });
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok("value");
        }
 
        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]string value)
        {
            return Created($"api/Values/{value}", value);
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public IActionResult Put(int id, [FromBody]string value)
        {
            return Accepted(value);
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public IActionResult Delete(int id)
        {
            return NoContent();
        }
    }
}

The main changes I’ve made so far are:

  • The return type of each action is now IActionResult, which allows for Http status codes to be returned.
  • For the GET actions, I’ve just wrapped the objects returned (which are simple strings) with the Ok result.
  • For the POST action, I’ve used the Created result object. This is different to OK because in addition to including an object, it also includes a URI pointing to the location of the object.
  • For the PUT action, I just wrapped the object returned with the Accepted result. The return type of Accepted is new in .NET Core v1.1 – this won’t compile if you’re targeting previous versions.
  • Finally, for the DELETE action, rather than returning void I’ve returned a NoContent result type.

I really like how .NET Core v1.1 bakes in creating great RESTful services in a clean and simple way and prefer it to the way previously used in .NET. I’m planning a number of other posts which will focus on some functional and non-functional aspects of creating a clean RESTful service:


About me: I regularly post about .NET – if you’re interested, please follow me on Twitter, or have a look at my previous posts here. Thanks!