Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/Development/DBWS/RestfulComponent/Design

< EclipseLink‎ | Development‎ | DBWS‎ | RestfulComponent
Revision as of 14:33, 18 October 2011 by Michael.norman.oracle.com (Talk | contribs) (DBRS URI Design)

DBRS Design

The DBRS utility starts by reading some initial configuration information:

prompt > DBRSBuilder [-builderFile {path to dbrsbuilder.properties}] -stageDir {path to stageDir}
         (if command-line arg -builderFile not present, default to look in current working directory)
prompt > DBRSBuilder running, connected to port 8884 ... Press <Return> to finish

dbrsbuilder.properties:

# builder properties
builder.port=8884
#builder.mode=production
builder.mode=test
builder.test.port=8885

# project properties
project.name=myproject
project.entities=employee, other entities ...

# database properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/db
db.user=user
db.pwd=password
db.platform=org.eclipse.persistence.platform.database.MySQLPlatform
logging.level=info

If the table name does not match the entity name, the user may specify an alias:

# project properties
alias.employee.tablename=EMP

The DBRS utility will login in to the database using the given database credentials and 'scrape' the meta-data for the employee table: column names and datatypes, PKs, foreign-key relationships, etc. If the built-in pluralization does not generate acceptible URIs, the user can add an alias for that as well - e.g. if the entity is person, the plural should be people, not persons:

# project properties
alias.person.plural=people

The DBRS utility operates at two levels:

  1. it builds RESTful applications (see below for more details on RESTful design principles); and
  2. it is itself a RESTful application that listens for messages that manipulates 'meta-resources', the in-memory representation of the meta-data for all entities in the project . This in-memory model is based on EclipseLink JAXB's OXM meta-data and EclipseLink JPA's ORM meta-data (javax.persistence.metamodel API):
    JPA2Metamodel.png
DBRS URI Design

Of primary importance is the design of the URIs for each resource (entity):

URI Operation Result
/myproject/entities/employees/
GET
PUT
POST
DELETE
retrieve list of employees (200 OK)
replace list of employees (201 Created)
add a new employee (201 Created)
unused (400 Bad Request)
/myproject/entities/employees/count GET with search modifier retrieve a count of the list of employees (200 OK)
/myproject/entities/employees/?pgNum=0&pgSize=40 GET with query parameters retrieve the first group of 40 employees (200 OK)

Message body should include the following additional information:

  • pageNum: reflects the pgNum query parameter (or 0 for the default first page)
  • pageSize: reflects the pgSz query parameter (or the default page size)
  • itemsInPage: reflects the total number of employees in the current page
  • totalItems: reflects the total number of employees
/myproject/entities/employee/{id}
GET
PUT
POST
DELETE
retrieve employee details (200 OK | 404 Not Found)
update employee details (201 Created | 404 Not Found)
add a new employee (201 Created)
remove employee (204 No Content | 404 Not Found)
DBRS meta-resources URI Design

In addition, the URIs for an entity's meta-resources:
Note: all properties in dbrsbuilder.properties can be accessed as resources

URI Operation Result
/dbrsbuilder/project/name GET retrieve the name of the current project (200 OK)
/dbrsbuilder/db/user PUT update the db.user property (201 Created)
/dbrsbuilder/alias/employee/plural PUT update the alias.employee.plural property (201 Created)
/dbrsbuilder/meta/model GET retrieve the meta-model for the current project (200 OK)
RESTful URI Design Principles

The term REST - REpresentational State Transfer - was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation (Fielding is one of the principal authors of the HTTP v1.1 spec). Conforming to Fielding's architecture is referred to as being RESTful. A RESTful web service (also called a RESTful web API) is implemented using HTTP and the principles of REST, with emphasis on the following aspects:

  1. definition of URIs for all resources exposed by the web service: e.g. /myproject/entities/car
  2. use of Internet media types for on-the-wire representation. This is often JSON or XML, but can be any valid Internet media type.
  3. use of the HTTP v1.1 operations: POST, GET, PUT, and DELETE - analogous to the database semantics of CRUD: Create, Retrieve, Update and Delete.
  4. use of hyperlinks to interact with/navigate to resources.

A URI is structured as follows: domainname/[contextual key(s)]/[resource name]/?[query args and modifiers] and should follow the following Design Principles:

  1. A URI must represent a unique object, permanently: if it becomes necessary to relocate a resource, use the response code HTTP 301 (redirect) so that the client can find where the resource has been moved to.
  2. should be succinct and easy-to-understand: /some/resource/about is preferred over /some/resource/about-acme-corp.
  3. A URI's structure must be consistent: once the strategy is chosen, follow it. As in 1), if the strategy changes, return HTTP 301 so that users familiar with resources under the previous structure can find them under the new structure.
  4. A URI must follow POLA - Principle Of Least Astonishment: URIs should be structured so that they are intelligibly 'hackable'. For example, if the URI /events/2010/01 represents the events for January 2010, then it follows that:
    /events/2009/01 - represents events for January 2009
    /events/2010 - represents events for the entire year of 2010
    /events/2010/01/21 - represents events for January 21st, 2010
  5. URIs should be composed of keywords that are important to the context of the resource. Typical contextual keys describe:
    a resource's type
    a resource's category - or parent category
    key resource data/attributes (i.e. the date posted)

    Typically, a URI specifies a categorization that moves from general to specific, e.g. a descending hierarchy like year -> month -> day
  6. A URI should not contain any markers that would allow someone to infer (correctly or otherwise!) what sort of underlying implementation technology is being used. Suffixes such as .php or .aspx should not be used.
  7. A URI should be lowercase up to the [resource name] - query args and modifiers can be mixed case. In addition, query args and modifiers change only the view presented for a resource, never its underlying representation. For example a chart service may show some rows from a database; a query modifier may indicate that the chart should be rendered as a PDF file instead of a PNG image - the presence of the query modifier should in no way alter the information contained in the rows.
  8. A URI that refers to a list of resources should use plural nouns; a URI that refers to a single resource should use singular nouns:
    GET /myproject/entities/employees - returns a list of employees
    GET /myproject/entities/employee/1 - returns the first employee
  9. Pagination of returned lists of resources is supposed to be managed via HTTP header attributes called HTTP Ranges. Unfortunately, this requires returning response code HTTP 206 (Partial Content) which is not universally accepted by clients. Thus pagination is typically accomplished by appending query modifiers to indicate page number and size:
    GET /myproject/entities/employees/?pgNum=0&pgSize=40 - returns the first group of 40 employees
    GET /myproject/entities/employees/?pgNum=1&pgSize=20 - returns the next group of 20 employees
To protect the server from 'greedy' clients that try to query the entire database, use the response code HTTP 413 (Request Entity Too Large) if necessary. The Entity tag (ETag) header, when used with Last-Modified/If-None-Modified/If-Modified-Since headers, is essential for handling the lost update problem when editing resources selected from (partial) paginated lists.

Back to the top