The backend Api servers are going to use the WebAPI component of ASP.NET 5 to make a RESTful api. Since I’m using entity framework for the database layer this is a remarkably simple piece of code, especially since most of it will be automatically generated.

Right now I’ll focus on the basic create/read/update/delete (CRUD) methods, later on I’ll get to some more interesting logic when it’s time for automatic transaction posting and budget forecasting.

As last time I’ll just show one class, since right now they’re almost identical. I’ll post snippets when I use more features later on, but right now I want to get enough backend code completed to start on the UI layer.

The Category Controller

ASP.NET 5 makes this pretty easy. Compared to WebAPI 2.0 there are fewer options but commonly used addons - such as dependency injection and attribute routing - are built in.

Let’s start the class

    [Route("api/categories")]
    public class CategoriesController : Controller
    {

The route is specified as an attribute. I think this is clearer since you always know the URI to your current class, no more magic string chopping to get the name. The biggest downside is there isn’t a central list of routes, but considering that most of the previous routes contained magic controller names I don’t think this changes much.

Next up member variables and the constructor

    private MHContext _Context;
    
    public CategoriesController(MHContext context)
    {
        _Context = context;
    }

Read actions

The Entity Framework context is injected in to the constructor by ASP.NET ready to go. Previously I tended to use Ninject for this, but the new built-in DI framework is perfectly adequate for this app. This context is bound to the request scope and automatically releases the connection at the end.

With that done it’s time for the basic CRUD methods. I’m going to ignore a lot of the setup for database loading, for example eager and lazy loading collections. I’ll add them as needed. First I’ll do the listing of all categories.

    [HttpGet]
    public IEnumerable<Category> Get() => _Context.Categories;

This is probably the simplest non-trivial method I’ve ever written. I don’t think this is going to be too common, normally there’ll be some sort of mapping and pagination going on here.

Write Actions

Now we want to get the detail on a specific category. This is a bit longer as I need to be able to return 404 not found on an invalid ID.

    [HttpGet("{id}")]
    public ActionResult Get(int id)
    {
        var category = _Context.Categories.FirstOrDefault(c => c.CategoryId == id);
        if (category == default(Category))
        {
            return new HttpNotFoundResult();
        }
        return new ObjectResult(category);
    }

I can’t use a specific type for the action result since there’s two possibilities - MVC 6 removed the HTTPResponseException. Fortunately I can use ActionResult and return the appropriate subtype, ObjectResult will handle serialisation for me.

That’s the read methods done, now for the writes. First I’ll define an object for the write APIs, I find it’s easier to follow than partially reading the underlying entity. This is generally what will happen for all APIs, including the read ones, but I’m being lazy.

public class ApiCategory
{
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsIncome { get; set; }
}

With that done the POST method can be added to create new categories

[HttpPost]
public void Post([FromBody]ApiCategory newCategory)
{
    _Context.Categories.Add(
        new Category
        {
            Name = newCategory.Name,
            Description = newCategory.Description,
            IsIncome = newCategory.IsIncome
        });
    _Context.SaveChanges();
}

I could use the asynchronous methods to run this, but given we’re talking to local SQLite databases I think the overhead of async is probably larger than the benefit. The frontend UI will be using async methods more.

I’m going to allow updates of name and description, so for that we need a PUT method

// PUT api/values/5
[HttpPut("{id}")]
public async Task Put(int id, [FromBody]ApiCategory newCategory)
{
    var category = _Context.Categories.First(c => c.CategoryId == id);
    category.Name = newCategory.Name;
    category.Description = newCategory.Description;
    await _Context.SaveChangesAsync();
}

And finally delete

[HttpDelete("{id}")]
public void Delete(int id)
{
    _Context.Categories.Remove(_Context.Categories.First(c => c.CategoryId == id));
    _Context.SaveChanges();
}

It’s all pretty simple now, but it’ll get interesting as we add more relations and expand our API.

Next up I’ll start on the UI, which will be more interesting.