Building a RESTful web service with ASP.NET Core

Posted on 06 September, 2016

In this blog post we'll see the easy step by step guide how to implement a RESTful web service using ASP.NET Core. I also build the project from empty project template to help you see how to implement the service from scratch without exiting project template.

Overview

The sample that I am going to build in this post is a RESTful service to manage contact list with GET, POST, PUT and DELETE methods. Below is the API details:

API Description Request body Response body
GET api/contacts Getting all contact records Empty A list of contacts
GET api/contacts/{contactId} Getting a contact record by contact id Empty One contact record
POST api/contacts Adding a new contact record Contact Contact
PUT api/contacts/{contactId} Updating an existing contact record Contact Empty
DELETE api/contacts/{contactId} Deleting an existing contact record Empty Empty

Creating project and setup dependencies

In Visual Studio go to menu File > New > Project then in the New Project dialog select .NET Core and choose ASP.NET Core Web Application (.NET Core) project template.


In ASP.NET Core Web Application (.NET Core) dialog select Empty template and click OK

Below is the empty project has created


We need to setup ASP.NET MVC for newly empty project by adding Microsoft.AspNetCore.Mvc dependency by open project.json file and add the following line to dependencies list

"Microsoft.AspNetCore.Mvc": "1.0.0"

Then the dependencies will look like this:

"dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.AspNetCore.Mvc": "1.0.0"
  }

To make ASP.NET Core MVC up and running we need to add these line of code to ConfigureServices method in Startup.cs file

var mvcCore = services.AddMvcCore();
mvcCore.AddJsonFormatters();

And adding this line of code to Configure method in the same class to start using MVC in application.

app.UseMvc();

Adding Contact model class

Adding a new folder named Models under the ContactManager project and creating a new class named Contact under Models folder.
The Contact class with properties to represent a contact record as below:

using System;
namespace ContactManager.Models
{
    public class Contact
    {
        public string ContactId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Address { get; set; }
        public DateTime Birthday { get; set; }
        public string Website { get; set; }
        public string Notes { get; set; }
    }
}

Adding repository classes and register it

Adding a new folder named Repository under ContactManager project. Then adding an interface named IContactRepository under Repository folder. This new interface define the basic CRUD methods as below:

using System.Collections.Generic;
using ContactManager.Models;
namespace ContactManager.Repository
{
    public interface IContactRepository
    {
        IEnumerable GetAll();
        Contact Get(string contactId);
        void Add(Contact newContact);
        void Update(Contact contact);
        Contact Remove(string contactId);
    }
}

To make the project simple, we won't connect to any database system but use a collection to store the data records in memory. Adding a new ContactRepository class under Repository folder to implement the IContactRepository with code as below:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using ContactManager.Models;
namespace ContactManager.Repository
{
    public class ContactRepository : IContactRepository
    {
        private ConcurrentDictionary contactList = new ConcurrentDictionary();

        public void Add(Contact newContact)
        {
            var newId = Guid.NewGuid().ToString();
            newContact.ContactId = newId;
            contactList.TryAdd(newId, newContact);
        }
        public Contact Get(string contactId)
        {
            Contact contact;
            contactList.TryGetValue(contactId, out contact);
            return contact;
        }
        public IEnumerable GetAll()
        {
            return contactList.Values;
        }
        public void Update(Contact contact)
        {
            contactList[contact.ContactId] = contact;
        }
        public Contact Remove(string contactId)
        {
            Contact contact;
            contactList.TryRemove(contactId, out contact);
            return contact;
        }
    }
}

ASP.NET Core has built-in support for dependency injection. In order to inject the repository class above I add this line of code to the Startup.cs file.

services.AddSingleton< IContactRepository, ContactRepository >();

I use the AddSingleton method here to make sure the repository class create only one instance in application.

Building the controller

Adding a new folder named Controllers under ContactManager project. Then adding a new class named ContactsController under Controllers folder. Define the new class with constructor and fields as below:

[Route("api/[controller]")]
public class ContactsController : Controller
{
    private IContactRepository contactRepository;
    public ContactsController(IContactRepository contactRepository)
    {
        this.contactRepository = contactRepository;
    }
}

Getting all contacts method

Implement following method in ContactsController class to get all contact records

public IEnumerable GetAll()
{
    return contactRepository.GetAll();
}

To get all contacts, the client will send a GET request to /api/contacts then ASP.NET Core MVC will route to this method and return an IEnumerable result that will be automatically serializes to JSON format.

Getting contact by contact id method

Adding following method to the ContactsController class

[HttpGet("{id}", Name = "GetContact")]
public IActionResult GetById(string id)
{
    var contact = contactRepository.Get(id);
    if (contact == null)
    {
        return NotFound();
    }
    return new ObjectResult(contact);
}

To get contact by contact id, the client will send a GET request to /api/contacts/{contactId} where {contactId} is the id of contact. The return result will be the contact item in JSON format, in case contact does not exist then return 404 HTTP error. Notice that this method also define the route named "GetContact" that will use in the next method.

Creating a new contact method

Add the following code to ContactsController class

[HttpPost]
public IActionResult Create([FromBody] Contact contact)
{
    if (contact == null)
    {
        return BadRequest();
    }
    contactRepository.Add(contact);
    return CreatedAtRoute("GetContact", new { id = contact.ContactId }, contact);
}

To create a new contact, the client will send a POST request to /api/contacts with request body is a contact in JSON format. When contact create success it will return a 201 response. The CreatedAtRoute method we use above also return with the content of newly contact as well as the URI of it. For example, if the newly contact's id is "0f8fad5b-d9cb-469f-a165-70867728950e" then the URI return will be like /api/contact/0f8fad5b-d9cb-469f-a165-70867728950e. The CreatedAtRoute method will based on the route name "GetContact" and id to generate the URI.

Updating the existing contact method

Add the following code to ContactsController class

[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody] Contact contact)
{
    if (contact == null || contact.ContactId != id)
    {
        return BadRequest();
    }
    var currentContact = contactRepository.Get(id);
    if (currentContact == null)
    {
        return NotFound();
    }
    contactRepository.Update(contact);
    return new NoContentResult();
}

To update existing contact, the client will send a PUT request to /api/contacts/{contactId} where {contactId} is the id of contact need to be update and the request body is a contact in JSON format. When contact update success it return HTTP 204 (No Content) result.

Deleting an existing contact method

Add the following code to ContactsController class

[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
    var currentContact = contactRepository.Get(id);
    if (currentContact == null)
    {
        return NotFound();
    }
    contactRepository.Remove(id);
    return new NoContentResult();
}

To delete a contact, the client will send a DELETE request to /api/contact/{contactId} where {contactId} is the id of contact need to be delete. When contact deleting success it return HTTP 204 (No Content) result.

Testing the RESTful service with Postman

I just finished coding the RESTful service. Now let press F5 on Visual Studio to run the application.


Now I have the RESTful service up and running. Next steps I'll use Postman to test it. Firstly it need to install Postman as an Chrome browser extension, it can be found here.

To testing the creating method, input the data as below screenshot then click Send to send the HTTP request. When the request success we will see the response body also return the contact record just created.


Let click to the Headers tab on Postman you also see the API also return the URI of the newly contact.


Now I use the URI of the new contact above then send a GET request to get the contact data.


Then I try to update the contact record that just created above by using HTTP PUT method with the request body is the contact data with different name field


After that send a get request to api/contact to get all contact records from server and see the data has been changed.

Conclusion

With the steps above I have finished building a very simple RESTful web service with support GET, POST, PUT and DELETE method.

Happy Coding!