You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Pam <ga...@yahoo.com> on 2011/06/10 23:45:27 UTC

REST Service - How to handle POST errors correctly

Hi,

I've got a REST service as below -

@POST
@Path("/createPdcUser")
@Produces("application/json")
@Consumes("application/json")
public Response createUser(CreateUser user) {
CreateUserResponse response = getAnonymousServiceManager().createPdcUser(user);
if (response.hasErrors()) {
return Response.status(Status.NOT_MODIFIED).entity(response).build()
} else {
return Response.status(Status.CREATED).entity(response).build()
}
}

The service must return a 201 CREATED http header on successfully creating a 
user.
On all validation errors, such as duplicate username exists, the service returns 
a 304 NOT_MODIFIED.
Is this the correct approach to REST?

A test then attempts to create a user via this REST service, it is defined below 
as -

import org.apache.cxf.jaxrs.client.WebClient;

public void testCreatePdcUserEmailsDoNotMatch() throws Exception {
CreateUser user = new CreateUser();
user.setEmail(email);
user.setConfirmEmail(StringUtils.isEmpty(confirmEmail) ? email : confirmEmail);
user.setPassword("password1x@xcom");
user.setConfirmPassword("password1x@xcom");
user.setUsername("username");
CreateUserResponse response = WebClient.create(USER_SERVICE_URL)
.path("/createUser")
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON)
.post(pdcUser, CreateUserResponse.class);
assertNull(response.getUserId());
assertEquals("The email address entered does not match. Please try again.", 
response.getErrors().get("confirmEmailAddress"));
}

However, when the test above is run, on a successful response (201), the call to 
WebClient.create returns the 'CreateUserResponse' object as expected.
On an unsuccessful response (304), the same call returns a null in 
the 'CreateUserResponse' object, even though the webservice includes a response.

1) is this the correct approach to writing a POST consuming REST service?
2) how can i extract the CreateUserResponse object when the REST service returns 
a 304?

Thanks,

Gavin

Re: REST Service - How to handle POST errors correctly

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

The "pure" way is to return 201, no message body and Location header
pointing to a new resource representing a created entity. If the
client is allowed to 'influence' the resource id allocation, ex, if a
server will use a user id allocated by the client for building a new
user URI reference, or if server prefers returning a new href as part
of the custom response then this 'pure' protocol does not have to
followed.

Responses between 300 & 400 are not really supposed to have any
message body returned, in fact, HTTP 304 status definition says 'must
not' in this regard

Cheers, Sergey

On Fri, Jun 10, 2011 at 10:45 PM, Pam <ga...@yahoo.com> wrote:
> Hi,
>
> I've got a REST service as below -
>
> @POST
> @Path("/createPdcUser")
> @Produces("application/json")
> @Consumes("application/json")
> public Response createUser(CreateUser user) {
> CreateUserResponse response = getAnonymousServiceManager().createPdcUser(user);
> if (response.hasErrors()) {
> return Response.status(Status.NOT_MODIFIED).entity(response).build()
> } else {
> return Response.status(Status.CREATED).entity(response).build()
> }
> }
>
> The service must return a 201 CREATED http header on successfully creating a
> user.
> On all validation errors, such as duplicate username exists, the service returns
> a 304 NOT_MODIFIED.
> Is this the correct approach to REST?
>
> A test then attempts to create a user via this REST service, it is defined below
> as -
>
> import org.apache.cxf.jaxrs.client.WebClient;
>
> public void testCreatePdcUserEmailsDoNotMatch() throws Exception {
> CreateUser user = new CreateUser();
> user.setEmail(email);
> user.setConfirmEmail(StringUtils.isEmpty(confirmEmail) ? email : confirmEmail);
> user.setPassword("password1x@xcom");
> user.setConfirmPassword("password1x@xcom");
> user.setUsername("username");
> CreateUserResponse response = WebClient.create(USER_SERVICE_URL)
> .path("/createUser")
> .accept(MediaType.APPLICATION_JSON)
> .type(MediaType.APPLICATION_JSON)
> .post(pdcUser, CreateUserResponse.class);
> assertNull(response.getUserId());
> assertEquals("The email address entered does not match. Please try again.",
> response.getErrors().get("confirmEmailAddress"));
> }
>
> However, when the test above is run, on a successful response (201), the call to
> WebClient.create returns the 'CreateUserResponse' object as expected.
> On an unsuccessful response (304), the same call returns a null in
> the 'CreateUserResponse' object, even though the webservice includes a response.
>
> 1) is this the correct approach to writing a POST consuming REST service?
> 2) how can i extract the CreateUserResponse object when the REST service returns
> a 304?
>
> Thanks,
>
> Gavin



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com