EveryREST - Let your users own their data

Motivation

A lot of my work is on cloud applications. Developing software to be hosted in the cloud offers many advantages over purchasing and running your own servers. However it also presents a number of challenges. One of the biggest drawbacks relates to the privacy of users’ data. A typical approach is to have a multi-tenant data store, such that each user can only access their own data. This architecture has a problem in that the system administrator has access to the whole database and therefore every user’s data. The alternative I’m proposing here is that the user should be the only person (assuming we can trust the service provider) with access to their data.

Cloud computing services have become very advanced and easy to use. Why not let each user own their own instance of a database and distribute a front-end separately? With that in mind, I developed EveryREST.

Introduction

EveryREST is little more than a RESTful wrapper for the Google Cloud Datastore. By RESTful here I mean designed to be a back-end for Ember Data, using the REST Adapter, with minimal configuration. The program does not handle any application logic, that must be done by the client side application (or an intermediate web service). Consequently developers can be confident that the back-end will “never” have to be updated. Any new features are added to the front-end application, which is shared by all users. The only information about users that needs to be stored centrally is reference to their instance of EveryREST, that is then secured by their Google account.

This is a work in progress. I know that the webservice works, but I have not tried to secure it to using Google acocunts yet.

API

The web service uses beerapi to handle requests. It responds to the following URLs. Where “beers” is a place holder for any resource name.

GET /beers/

Returns a list of the beer records. Example response:

{
  "beers": [
    {"id": "1", "name": "Castle", "type": "Lager", "comments":["1", "2"]},
    {"id": "2", "name": "Woodhouse", "type": "Ale", "comments":["3", "5", "7"]}
  ]
}

GET /beers/id

Get a single record.

{
  "beer": [
    {"id": "1", "name": "Castle", "type": "Lager", "comments":["1", "2"]},
  ]
}

GET /beers?ids[]=1&ids[]=2

Get all the specified records, response is the same as that for GET.

POST /beers/

Create a new record. Example request payload:

{
  "beer": {"name":"Castle","type":"Lager","comments":[]}
}

PUT /beers/id

Update the specified record. Request is the same as POST.

DELETE /beers/id

Delete the specified record.

Deploy

Anyone can deploy a version of this web service for themselves.

Client application

The service doesn’t care what kind of application consumes it, and is set up with CORS allowing any IP by default. Checkout my post for an example of a very simple Ember application powered by this server.