The document discusses best practices for designing REST APIs using the JAX-RS implementation CXF. It covers REST architectural principles, designing resources and URIs, representations with JSON and XML, errors, asynchronous processing, and transactions. The goal is to provide practical lessons learned from building the Syncope REST API to help others design RESTful services with CXF.
1 of 59
Download to read offline
More Related Content
Andrei shakirin rest_cxf
1. Design REST Services with CXF JAX-
RS implementation: best practices
and lessons learned
Andrei Shakirin, Talend
ashakirin@talend.com
ashakirin.blogspot.com
2. Agenda
• REST architectural style
• Design of REST API for Syncope domain
• Practical aspects of using CXF JAX-RS
3. About Me
• Software architect in Talend Team
• PMC and committer in Apache CXF and
commiter in Apache Syncope projects
• Speaker for Java conferences
4. Representational State Transfer
• Set of principals and restrictions
• HTTP is one instantiation of the REST
• The scope of REST architectural style: loosely
coupled application
5. REST Principles
1. Everything has an ID
2. Using IDs to link things together: hypermedia
and HATEOAS
3. Uniform interface
4. Interaction with resources through the
representation
5. Communication is stateless
6. JAX-RS
• Specification and Java API
• Support in exposing a resource Java class (a
POJO) as a web resource
• Versions: 1.0, 1.1, 2.0 (client API,
asynchronous API, filters and interceptors)
• Implementations: Jersey, Apache CXF,
Resteasy, …
10. Resources and URIs: Rules
• Resource is anything to be referenced
• Normally resources are the nouns
• Resources are coarse grained
• URIs: descriptive and well structured
• URIs: scoping information
12. Resources Types
1. Predefined top-level resources
2. Resource for collection of objects
3. Resource for every exposed objects
4. Resource representing results of algorithms
13. Top Level Resources
• Entry point to the API
• Home page or list of root entities (collections)
URIs:
http(s)://api.syncope.org/administration
vs
http(s)://api.syncope.org/administration/rest/jaxrs/c
xf
17. Subset of Uniform Interface
Will the client will fetch resource of this type?
GET /users
GET /users/a1b2c3
18. Subset of Uniform Interface
Will the client delete resource of this type?
DELETE /users/a1b2c3
19. Subset of Uniform Interface
Will the client modify resource of this type?
PUT /users/a1b2c3
20. Subset of Uniform Interface
Will the client create resource of this type?
Who is in charge to determine URI: server /
client?
Server:
POST /users
201 Created, Location=/users/a1b2c3
Client:
PUT /users/myuser
26. JSON: Jettison vs Jackson
CXF JSONProvider (based on Jettison)
• Adopt XML structures to JSON (mapped,
BadgerFish)
• STaX API (XMLStreamWriter, XMLStreamReader)
• Flexible and simple (prefixes, root elements, array
serialization, unwrapping, XSLT transformations)
• Using: for small payloads, if flexibility required
<root><child>test</child><child>test</child></root>
{ "root" : { child : [ "test", "test" ] } }
27. JSON: Jettison vs Jackson
Jackson
• Not XML oriented
• Supports streaming, tree and data binding
models
• Supports Jackson specific annotations
• Using: middle and large payloads, sophisticated
class hierarchy
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY,
property="class")
33. Errors
• Choose appropriate HTTP status code
• Set short error code for automatic processing
• Provide informative and descriptive entity-
bodies
• Use JAX-RS ExceptionMappers
34. Errors: Code Mapping
1. Decide is it client or server problem (4xx/5xx)
2. Look into HTTP status code spec and select
approprite one:
• Entity Not Found -> 404 Not Found
• Entity Already Exist -> 409 Conflict
• IllegalArgumentException -> 400 Bad Request
35. Errors: HTTP Response
404 Not found
X-Application-Error-Code: EntityNotFound
X-Application-Error-Info: entity=user,id=a1b2c3
{
A user ‘a1b2c3‘ is not found in Syncope storage. Check if
user name is correct. Refer following link for the details:
https://cwiki.apache.org/confluence/pages/viewpage.acti
on?pageId=30751185/
}
37. Errors: ExceptionMappers
@Provider
public class RestServiceExceptionMapper implements
ExceptionMapper<SyncopeClientException> {
@Override
public Response toResponse(final SyncopeClientException ex) {
LOG.error("SyncopeClientException thrown by REST method: " +
ex.getMessage(), ex);
builder = ex.isComposite() ?
getSyncopeClientCompositeExceptionResponse(ex.asComposite())
: getSyncopeClientExceptionResponse(ex);
return builder.build();
}
}
38. Asynchronous Processing
• Model operations taking a long time
• Provide non-blocking calls on the client side
• Provide suspended responses on the server
side
40. Asynchronous: Client API
InvocationCallback<Response> callback =
new InvocationCallback {
public void completed(Response res) {
System.out.println("Request success!");
}
public void failed(ClientException e) {
System.out.println("Request failed!");
}
};
client.target("http://mysyncope.org/tasks")
.request()
.async()
.post(myEntity, callback);
41. Asynchronous: Server API
@Path("/connectors")
public class AsyncResource {
@GET
public void asyncGet(@Suspended final AsyncResponse asyncResponse) {
new Thread(new Runnable() {
@Override
public void run() {
String result = readConnectors();
asyncResponse.resume(result);
}
private String readConnectors() {
// ... very expensive operation
}
}).start();
}
}
46. Conclusion
• Try to follow REST and RESTful HTTP principles
by design your application
• Consider using JAX-RS 2.0 implementation for
Java applications
• CXF is nice alternative with active, responsive
and cooperative community
53. GET, HEAD
• READ semantic
• Must be safe and idempotent
• Cacheable
• Can be conditional or partional
GET /users/a1b2c3
54. DELETE
• DELETE semantic
• Not safe, Idempotent
• Resource doesn‘t have to removed
immediately
• Can return the resource representation or
other payload
DELETE /users/a1b2c3
55. PUT
• Can be used for UPDATE and for CREATE
• Not safe, idempotent
• Not for partial updates
PUT /users/a1b2c3
{
“username“:“testUser“
“status“:“active“
…
}
56. POST
• Can be used to do anything (normally create or
update)
• Neither safe, no idempotent
POST /users
{
“username“:“testUser“
“status“:“active“
…
}
Response:
201 Created, Location=/users/a1b2c3
57. Resources and URIs: Rules
• Resource is anything to be referenced
• Normally resources are the nouns
• Resources are coarse grained
• URIs: descriptive and well structured
• URIs: scoping information