-
Notifications
You must be signed in to change notification settings - Fork 3
Best Practises for data driven REST Applications
Peter edited this page Apr 9, 2014
·
3 revisions
The following is a set of best-practises recommendations for building data-driven RESTful applications in the framework. It is designed to be read alongside the Your First RESTful Application guide.
- Database entities as beans with annotations on private fields and auto-generated getters/setters, named with the suffix "Entity", for example
UserEntity- UsingLongas a numeric id,Stringas a string id - Avoiding composite primary keys for the sake of simplicity of hibernate operation -@Columnannotations assigning db-style names (e.g.email_addressrather thanemailAddress) - Database access object with an interface (e.g.
UserDao), extendingDao<UserEntity, PrimaryKeyType>- Queries expressed as methods on this dao (e.g.
getByEmailAddress(String email)).
- Queries expressed as methods on this dao (e.g.
- Database access object impleentation for Hibernate (e.g.
UserDaoImpl), extendingHibernateDao<UserEntity, PrimaryKeyType>- Methods implemented with
@Transactionalto act as a last resort boundary for starting a db transaction
- Methods implemented with
See an example of a simple service as part of the Your First RESTful Application guide
- REST service to expose the data via API.
UserRestServiceinterface- Resources structured as:
-
GET /user/{id}- retrieve single user document (return 404 if not exist) -
PUT /user/{id}- update (post a user document here), returns the same as GET -
DELETE /user/{id}- delete a user (may mark as inactive) -
POST /users/create- create a new user (by posting a user document or, in more complicated cases, a user creation request document). Returns the same as GETting the newly-created user -
GET /users- execute a query (expressed on the query string - [a dynamic query, for instance](WebQuery API)) across all users. Designed for web UI and developer use -
POST /users- execute a query (expressed in a query document) across all users. Designed for other services. Same return type as GET /users above usually -
POST /user/{id}/action/{action-name}- perform some action (often POSTing a document or some form parameters)
-
- Use of
@Docannotation on interface, methods and parameters to help improve quality of auto-generated service docs exposed via /list resource - Access Control via
@AuthConstraintannotations
- Resources structured as:
- JAXB document classes for REST service inputs/outputs, implemented as POJOs (no getters/setters, public fields with annotations).
- Named as Entity classname without Entity suffix (e.g. simply
Userfor a user document). -
@XmlRootElement(name="User")and@XmlType(name="UserType")annotations - Request/Response documents with Request or Response suffix (e.g.
MigrateUserRequest)
- Named as Entity classname without Entity suffix (e.g. simply
- Internal service class,
UserService, where both API and others will need to make changes in a managed way (e.g. state transitions) - REST service implementation named as "
UserRestServiceImpl", talking to DAO or, where appropriate, an internal service-
@Transactionalor@Transactional(readOnly=true)annotations on REST method boundaries
-
- Converter class to convert the database entity bean to JAXB documents. Depending on use this may be a
UserConverteror a single Converter for the whole service (e.g. where converting a graph of objects and their relations)- Two main methods,
marshalto convert an Entity -> JAXB type andunmarshalto convert a JAXB type -> partially filled in Entity - Converter usually not DAO aware
- Complex relationship expansion may be controlled by a flag (to allow entities to return lots of data on their related objects, but without creating circular references loop or ending up with the whole db in a single xml entity response as more and more relationships are expanded)
- Two main methods,
- UI service to expose the data to users.
UserUIServiceinterface (in service project, usually annotated with@ImplementedBy(UserUIServiceImpl.class)for less guice module wiring)- Similar (or identical) endpoints to the API Service, with the exception of search which doesn't require a POSTed XML document approach and can survive on the query string approach.
- Use Accept header negotiation to return UI method instead of API method (e.g.
@Provides("text/html")vs@Provides("application/xml")) - Create/Modify resources redirect to
GET /user/{id}page on success rather than returning the getter as with RestServices
- UI service implementation,
UserUIServiceImpl-
java @Transactionalor@Transactional(readOnly=true)annotations on REST method boundaries - Calls DAOs or, where appropriate, custom services (
UserService, for example) - Uses a templater to present database entities, emitting String documents via JAX-RS (done at this point so the template can be generated while the hibernate template is still valid, since it may be needed to expand lazy relationships used in the template)
- Access Control via
@AuthConstraintannotations
-