REST as C in MVC

It’s been a couple of years since REST style HTTP resources have become one of the first choices of exposing HTTP services in different platforms. They are often referred as RESTful web services. The fact that REST style makes it much simpler to expose a service may also have a side effect: One may gradually fall out of standard HTTP implementation for a REST service. RESTful web services is documented in RFC 2616. Let’s consider an example. I have an interface that defines an abstraction for a bank account service:

interface BankAccountService {
    double getBalance(String id);
    double deposit(String id, double amount);
    double withdraw(String id, double amount);
}

Quite simple. What different implementations of the interface can come to mind?

  • A data backend implementation such as JPABankAccountService
  • An in-memory (dummy) implementation for testing purposes such InMemoryBankAccountService
  • A REST implementation such as BankAccountServiceResource?

So, what’s wrong with the third option? It looks neat, serves as a true implementation of the interface besides it also exposes the service through REST. Let’s have a closer look.

When thinking in resources, I should be able to model a bank account as a resource. To identify a bank account, I probably should use the bank account; so it should look like roughly as /accounts/112233 which should resolve to the REST resource identified by the account number. Having the resource, I can get the balance and perform other operations, right? Everything looks fine until, for instance, I’d use a resource path such as above for which there is no bank account. By RFC, this should be a standard 404 response code. Bam! I’m stuck! My implementation observes the interface and cannot return HTTP response codes!

The problem roots in the fact the a REST resource should not directly implement an interface behavior. REST should be considered similar to that of a layer of “controller” in MVC. A controller is a layer over different service implementation objects so it should not directly provide (update the model) the service operations. So, to have a REST resource for bank account service, you should already have a service implementation. And, this actually makes the REST resource more flexible as you can have different REST resources over different implementations. For instance, we can have a REST resource that uses the JPA backend to provide the services:

public class BankAccountServiceResource {
    private final BankAccountService service;

    public BankAccountServiceResource(BankAccountService service) {
      this.service = service;
    }

    @GET
    @Path("/acounts/{id}")
    public Response getBalance(@PathParam("id") String id) {
      if (service.getBalance(id) == -1) {
        return Response 404!
      }
      return Response(service.getBalance(id));
    }
}

I wrote this piece since I’ve come across many mind sets including myself that start to expose a REST resource in the first place directly with the business interface.

Leave a Reply

Your email address will not be published. Required fields are marked *