0
votes

I'm new to REST services, I have an Angular2 client calling a RestEasy JAX-RS service. All I am trying to get is a "Hello World" message in JSON format. I was expecting only a JSON object, but I get my response with the following structure:

_body: "{"message":"Hello World!!"}"
 headers: t
 ok: true
 status: 200
 statusText: "OK"
 type: 2
 url: "http://localhost:8080/helloapp/rest/hello/world"
 __proto__: ...

My question is, Is that the way it should be?

I mean, I thought I would be able to access the JSON object straight from the response. Something like

this.service.getHello()
.then( result => {
  console.log(JSON.parse(result)); //{message: "Hello World"}
  this.message = JSON.parse(result).message;
});

But I actually have to get it from _body:

   this.service.getHello()
    .then( result => {
      this.message = JSON.parse(result._body).message;
      console.log(this.message);//Hello World
    });

Is it a RestEasy configuration thing, is there a way to change that?

Or

Should I consider that I will always have a field _body in my response with my data, and that's the default response structure?

For eventual consideration, here is my backend code:

HelloWorld Service:

@Path("/hello")
@Produces({ "application/json" })
@Consumes({ "application/json" })
public class HelloWorld {

    public HelloWorld() {}

    @GET
    @Path("/world")
    public Message getHello(){
        return new Message("Hello World!!");    
    }
}

My RestEasy version is 3.1.1.Final running in Wildfly 10.1.0.Final

2

2 Answers

2
votes

What you're getting back is the Response object from the Http request. This is what all Http operations will return. The easiest way to parse the JSON from that is to just call the json() method on it

this.service.getHello()
    .then((res: Response) => {
      let obj = res.json();
    });

If you want the getHello to just return the object without having to parse it (on the calling client), then you can do it inside the getHello method by mapping it (using the Observable.map operation)

getHello() {
  this.http.get(..)
    .map((res: Response) => res.json())
    .toPromise();
}
1
votes

As peeskillet says above, you're getting back the entire Response from the request, and while sometimes you may want to examine the headers, perhaps to handle the different return conditions (retry or redirect on 4xx or 5xx responses for example), most of the time we assume a successful request and we just want the payload.

Angular2 encourages the use of Observables, so your service might look something like this:

getHello() 
{
return this.http.get(http://localhost:8080/helloapp/rest/hello/world)
}

And your component may look something like this:

data: string;

ngOnInit() {
 this.service
     .getHello()
     .map(response => response.json())
     .subscribe (
          data => {
                this.data = data, 
          },
          err => console.log('Error',err),
          () => console.log('data',this.data) 
     );
}

You call the service, which is an http.get() and returns an Observable object, and we use .map to parse the response as JSON, which also returns an Observable, which we subscribe to.

Subscribe has three callback functions, .subscribe(success, failure, complete)

In the example above on success we assign the payload - data - to this.data, if the subscribe fails, you log the error, and when it completes, we can do whatever we like, but in this case, we log this.data to the console - that's optional, but I log out the results while developing and then strip them out later.