Designing a (somewhat) RESTful Database User Interface

To continue exploring the design of a generic database user interface, let us turn our attention to a web interface. I’ll use the pattern of the Django admin application as the basis for specifying the behavior of a somewhat RESTful web interface for maintaining the movies database I’ve used in previous posts.

Home Page

The home page (canonically at is comparable to the menu displayed initially by the command line interface (CLI). It will consist of an HTML table listing the logical entities together with options to add a new record (New) or edit an existing one (Edit). For now, the table will include a single entity: a film.

The latter option (or the entity link itself) will take the user to the List Records Page (see below). The New option will go to the

Add Record Page

This will be presented at and is comparable to the Add interactions in the CLI. It will have an HTML form with fields (HTML text input or textarea elements) for each attribute and a “Save” button (HTML submit input element). Pressing the button will POST the new data to

List Records Page

This is of course comparable to the CLI List display. It will feature an HTML table listing all films. This is the index page for the entity so its URL will be

We’ll worry about pagination later, but when we do the URL will have a query string to select a given page, e.g.,

Each row of the HTML table will have a link that leads to the

Record Edit Page

This will have a URL that identifies the film being edited, e.g.,, where 23969 corresponds to a value in the id column of the film table in our database. This is equivalent to the CLI Update option.

The Edit page will have the same HTML form as the Add Record page, including the “Save” button, but the POST will go to It will also have a “Delete” link that goes to the

Record Delete Confirmation Page

This will be presented at and is comparable to the confirmation requested by the CLI Delete. It will display an “Are you sure?” message together with details of the record to be deleted and a button titled “Yes, I’m sure.” The POST will use the same URL as the GET.

Form and Error Handling

Both the Add and Edit pages will validate the data entered. If there are any errors, the respective page will be redisplayed with a message(s) indicating what needs to be corrected. If a “Save” operation succeeds, we’ll redisplay the film listing.

Entity Handler

With this specification, if we translate each URL path above into a class method, we can outline a Python class that will act as the handler (or MVC controller, although Django calls this the view layer) for the HTTP requests. Note that the entity index URL (the listing) maps to the index method while the specific entity URL maps to the default method.

class FilmHandler(object):
    def new(self):
        "Displays a form to create a new film"

    def create(self, **formdata):
        "Saves the film submitted from ``new``"

    def index(self):
        "List all films"

    def default(self, id=None):
        "Displays a form for editing a film by id"

    def save(self, id=None, **formdata):
        "Saves the film submitted from ``default``"

    def delete(self, id=None):
        "Deletes an existing film by id"

There are many more details such as the “Model,” i.e., the interface to the database itself, and the MVC View (which Django calls the template layer). So visit again if you’re interested!

Update: Changed title and first paragraph to emphasize that the interface does not adhere strictly to the REST canon. See Oliver Charles’ detailed critique below.

9 thoughts on “Designing a (somewhat) RESTful Database User Interface

  1. Berend is correct, this is much more RPC, and barely REST.

    “Add Record Page: This will be presented at” This isn’t really part of REST at all (unless the new film page happens to be a resource), so it’s debatable how correct it is. Obviously you need somewhere to create films from though, so this seems acceptable.

    “Pressing the button will POST the new data to

    No, the form should POST to /films. Notice I’m using a plural resource here too. POST means “append to this resource” so we are appending a new film to the films resource.

    “List records page” Should be /films, not /film.

    “Record Edit Page” again, not part of REST – because REST isn’t concerned with the user interface. However, /film/{id} should fetch the film resource primarily, if you want to add an edit form their that should be that URIs *secondary* purpose.

    “The Edit page will have the same HTML form as the Add Record page, including the “Save” button, but the POST will go to

    No. The edit form, wherever it is, should be a PUT request to /film/{id}. PUT means “replace content” effectively.

    “” Should be /film/{id}/delete (hierarchical URI). It should also submit DELETE /film/{id} (sending a DELETE request to the resource being deleted).

    • Thanks for the detailed response. As I stated early in my post, I was following the Django admin pattern, so perhaps that’s not as RESTful as some would think. For the record, the URLs for a test Django admin app, are as follows:

      /admin/ — Menu, lists “Films” with Add and Change buttons
      /admin/test/film/ — List of films
      /admin/test/film/add/ — Add a film page
      /admin/test/film/add/ — URL to which “add” is POSTed
      /admin/test/film/{id}/ — Change film page
      /admin/test/film/{id}/ — URL to which “change” is POSTed
      /admin/test/film/{id}/delete/ — Delete confirmation page
      /admin/test/film/{id}/delete/ — URL to which “delete” is POSTed

      So, perhaps the title of my post shouldn’t have been “Designing a RESTful Database User Interface” but rather “Designing a Django-admin-like Database User Interface.” In any case, this will probably not be the final design, but more an exploration of an interface that I have found useful.

      To give proper credit where it’s due, the design was also influenced by James Gardner’s SimpleSite tutorial (available here).

  2. Hi Joe,

    Interesting article. I am a recent Python convert and have been trying to design my own generic template database CRUD classes which (I’m pleased to say) have turned-out similar to your FilmHandler example. If you are willing to disclose it, I would be interested to see what generic code you have inside the new, create, save, etc. methods within the class. Is that possible, or is it something you had planned to post to the blog in the future?


    • Hi Alan,

      The idea behind these series of posts is to develop a database interface application generator for Pyrseas, somewhat like Andromeda has. So yes, I’ll be disclosing more of the generic code as I go along.


  3. Pingback: Joe Abbate: Designing a RESTful Database User... | PostgreSQL | Syngu

  4. Pingback: A Minimalist WSGI Database User Interface | Taming Serpents and Pachyderms

  5. Pingback: Dueling Frameworks, revisited | Taming Serpents and Pachyderms

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.