valik
valik

Reputation: 2094

How to call an external API with vertx and return data to java object

I am trying to create a vertx client that calls an external API and gets data using a Java model.

An example of what I want to do is this, below is just a rough work

WebClient client = WebClient.create(vertx);

// Send a GET request
client
  .get(8080, "mytour.mycompany.com", "/getRusult?pricemin=0&priceMax=1000&beach=true....etc")
  .send(ar -> {
    if (ar.succeeded()) {
      // Obtain response
      HttpResponse<Buffer> response = ar.result();

mytour is an external API and I want to return the data gotten from the call to my java class already designed for this. The java class below is not completely displayed for brevity but it follows the builder pattern principles. I want to the data gotten from API call to this class.

public class Tour {

    private Departure departure;
    private Arrival arrival;
    private TourType tourType;
    private Hotel hotel;
    private Beach beach;
 private Tour() {
        }

I am not sure how to go about it any ideas, please. At this point here is what i did in other to get tour object from Buffer any idea how to do this ?

    public Tour clientTest() {
        Vertx vertx = Vertx.vertx();

        WebClient client = WebClient.create(vertx);

// Send a GET request
        client
            .get("https://www.mytour.com/tariffsearch/getResult?" +
                "priceMin=0&priceMax=1500000&currency=533067&nightsMin=6&nightsMax=8" +
                "&hotelClassId=269506&accommodationId=2&rAndBId=15350&tourType=1&" +
                "locale=ru&cityId=786&countryId=1104&after=01.08.2018&before=01.08.2018&" +
                "hotelInStop=false&specialInStop=false&version=2&tourId=1285&" +
                "tourId=12689&tourId=12706&tourId=143330&tourId=9004247&" +
                "tourId=4433&tourId=5736&tourId=139343&tourId=4434&tourId=12691&" +
                "tourId=21301&tourId=12705&tourId=149827&tourId=4151426&hotelClassBetter=true&" +
                "rAndBBetter=true&noTicketsTo=false&noTicketsFrom=false&searchTypeId=3&" +
                "recommendedFlag=false&salePrivateFlag=false&onlineConfirmFlag=false&contentCountryId=1102")
            .send(ar -> {
                if (ar.succeeded()) {
                    // Obtain response
                    HttpResponse<Buffer> response = ar.result();
                    Tour tour = (Tour) response.body();

                }
             });
    }

Upvotes: 2

Views: 2578

Answers (2)

Tim
Tim

Reputation: 36

I think I understand what you are asking and for the most part I use the reactive version of the methods for my calls. The reasoning for this is to process the data as though it was a stream rather than handling potential nested callbacks.

Example Kotlin code:

webClient.get(PORT, URL)
   .rxSend()
   //convert to observable stream
   .toObservable()
   //get responsebody as a jsonarray of objects
   .map { response: HttpResponse<Buffer> ->
          response.bodyAsJsonArray().toMutableList() as List<JsonObject>}
   //segment the array into a stream of single object                
   .flatMap { objs: List<JsonObject> -> Observable.fromIterable(objs)}
   //convert each object the json object stream into a java object
   .map {entry:JsonObject -> Json.decode(entry, Tour.javaClass)}

After this code executes you would have an Observable<Tour> which you could stream through and do any processing you want to on the Tour Objects or you could just call toList() to convert to Single<List<Tour>> and in the subscribe method handle returning the response back to the caller.

If you have any questions let me know!

Upvotes: 1

Piotr Wittchen
Piotr Wittchen

Reputation: 3922

I want to return the data from the API call to my Tour class

Instead of casting a response.body() into Tour type like that:

HttpResponse<Buffer> response = ar.result();
Tour tour = (Tour) response.body();

you should convert body into an object (POJO). You can do that in at least a few ways. First, take a look at the JavaDoc of the Vert.x HttpResponse class here: https://vertx.io/docs/apidocs/io/vertx/ext/web/client/HttpResponse.html. We have e.g. method like: response.bodyAsString(). Once we've got response body as a String and assuming that this String contains a response in a JSON data format, we can convert this String into our object e.g. using Gson library or another solution.

For example:

HttpResponse<Buffer> response = ar.result();
String bodyAsString = response.bodyAsString();

Gson gson = new Gson();
Tour tour = gson.fromJson(bodyAsString, Tour.class);

After that, when Tour object is compatible with JSON HTTP response you should have your response data mapped into the Tour object.

I don't know the structure of your HTTP response. If Tour object is not compatible with HTTP response, then you should create another object - e.g. TourResponse, which will be compatible with this response and create a mapper, which will convert TourResponse into Tour object.

Upvotes: 2

Related Questions