-
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
- UsingLong
as a numeric id,String
as a string id - Avoiding composite primary keys for the sake of simplicity of hibernate operation -@Column
annotations assigning db-style names (e.g.email_address
rather 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
@Transactional
to 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.
UserRestService
interface- 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
@Doc
annotation on interface, methods and parameters to help improve quality of auto-generated service docs exposed via /list resource - Access Control via
@AuthConstraint
annotations
- 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
User
for 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-
@Transactional
or@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
UserConverter
or a single Converter for the whole service (e.g. where converting a graph of objects and their relations)- Two main methods,
marshal
to convert an Entity -> JAXB type andunmarshal
to 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.
UserUIService
interface (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 @Transactional
or@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
@AuthConstraint
annotations
-