Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use MicroProfile Rest Client with many parameters #286

Open
jdang67 opened this issue Jul 23, 2020 · 7 comments
Open

How to use MicroProfile Rest Client with many parameters #286

jdang67 opened this issue Jul 23, 2020 · 7 comments
Labels
Milestone

Comments

@jdang67
Copy link

jdang67 commented Jul 23, 2020

Hi Everyone,

I want to use MicroProfile Rest Client. However, I need to talk to the endpoint like the following:

http://localhost:8083/serviceName/sub/abc?p1=val1&p2=val2&p3=val3@p4=val4

and here is the
the base URL: http://localhost:8083

    @GET
    @Path("/serviceName/sub/abc/")
    @Produces(MediaType.APPLICATION_JSON)
    public String test(@DefaultValue("val1") @QueryParam("p1") String p1,
                                   @DefaultValue("val2")  @QueryParam("p2") String p2,
                                   @DefaultValue("val3")  @QueryParam("p3") String p3,
                                   @QueryParam("val4") String p4);

Using the URL directly always returns data while using rest-client throws exception:

RESTEASY004655: Unable to invoke request: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8003 [localhost/127.0.0.1, localhost/0:0:0:0:0:
0:0:1] failed: Connection refused: connect

Anything wrong with the way I use the MicroProfile Rest Client?

thanks,

Jdang

@andymc12
Copy link
Contributor

Hi @jdang67 , I think there may be a typo in your configured base URI. The error message says it is trying to connect on port 8003, but you said that the service was listening on port 8083. You’ll probably just need to change the base URI in you MP Config or builder code. Other than that, everything else looks good to me.

HTH, Andy

@jdang67
Copy link
Author

jdang67 commented Jul 23, 2020

Hi Andymc12,

Yes, I made a mistake on the port #. However, it complains about the input param.
Looks like the framework fails to send the "service" parameter?

// actual request that works
http://localhost:8083/geoserver/omi/ows?service=WFS&version=2.0.0&request=GetFeature&count=10&outputFormat=application%2fjson&exceptions=application%2fjson&propertyName=mmsi%2clat%2clon%2cdtg%2cimo%2ccall_sign%2cvessel_name&typeName=omi%3aais-enriched-stream&CQL_FILTER=(DWITHIN(geom%2c+POINT+(39.5783+121.2671)%2c+500%2c+Meters))

 <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
    <ows:ExceptionText>No service: ( ows )</ows:ExceptionText>
  </ows:Exception>

And this is the actual interface

  @GET
    @Path("/geoserver/omi/ows/")
    @Produces(MediaType.APPLICATION_JSON)
    public String getVesselsNearBy(@DefaultValue("WFS") @QueryParam("service") String service,
                                   @DefaultValue("2.0.0")  @QueryParam("version") String version,
                                   @DefaultValue("GetFeature")  @QueryParam("request") String request,
                                   @DefaultValue("10")  @QueryParam("count") String count,
                                   @DefaultValue("application/json")  @QueryParam("outputFormat") String outputFormat,
                                   @DefaultValue("application/json")  @QueryParam("exceptions") String exceptions,
                                   @DefaultValue("mmsi,lat,lon,dtg,imo,call_sign,vessel_name") @QueryParam("propertyName") String propertyName,
                                   @DefaultValue("omi:ais-enriched-stream")  @QueryParam("typeName") String typeName,
                                   @QueryParam("CQL_FILTER") String cqlFilter );

In this case, the only parameter that can be changed is the CQL_FILTER, the rest should be static.
How do I check the actual request that sends to the server?
What should be on the base URL, path?

thanks,

Jdang

@andymc12
Copy link
Contributor

What value are you passing for the service parameter on the client side? @DefaultValue is only required to work on the server side (JAX-RS) - though implementations could make use of them in non-portable ways (for example, they could convert a null parameter to the value specified in the annotation). Supporting @DefaultValue sounds like a good feature request for the spec...

I've found that the best way to see what is sent from the client is to use a utility like tcptunnel ( https://github.com/vakuum/tcptunnel ). With this tool, you basically create a logging proxy - for example:
tcptunnel --local-port 10001 --remote-host localhost --remote-port 8083 --stay-alive --log will listen on port 10001 and then forward anything it receives to localhost port 8083 - and log the request and response in the console.

Then you can change your baseURI in the MP Rest Client to point to localhost:10001 and you can see exactly what is sent and what is received.

Different MP Rest Client implementations may also have different tracing options to see what exactly is sent, but generally I've found this approach to work fairly consistently - iirc, it does have problems with SSL/HTTPS though...

HTH,
Andy

@jdang67
Copy link
Author

jdang67 commented Jul 23, 2020

Andy,

The value of service param is "WFS" and currently supply by the @DefaultValue("WFS").

John

@andymc12
Copy link
Contributor

John,

Are you using the same interface for both the client and the server? The @DefaultValue("WFS") will only take effect on the server - and the default value ("WFS") should only be used if there is no query parameter from the client request.

What I suspect is happening is that when you invoke the client, you may be passing null to the client interface parameter, expecting that the client implementation of the interface will then use the default value, but that is not currently a spec-defined behavior. Instead, what I suspect would happen is that the client implementation will generate a request that includes a query parameter like this: ?service=null If I'm right, then I think "null" (the string, not an actual null value) would be passed to the JAX-RS resource on the server side - and that would likely result in an error.

The tcptunnel approach should help determine what is actually sent to the server.

HTH,
Andy

@jdang67
Copy link
Author

jdang67 commented Jul 29, 2020

Andy,

Sorry for the late response since I have to implement the HttpClient by myself.
You are right, I have to pass all null for params which are always the same. I cannot pass only the param that requires.
Looks like MicroProfile Rest Client has a problem with design?

John

@andymc12
Copy link
Contributor

I would look at it as an opportunity to improve the design. ;-)

It is probably too late to add support for @DefaultValue in the 2.0 release, but I think it is a good feature request.

One of the problems with supporting @DefaultValue is that the value in the annotation must be a String. That works fine for types that are easily initialized from a string value, but no so much for custom types, etc. The server side already supports ParamConverters that would convert strings to objects - so maybe the Rest Client would need to support them as well for converting default values to non-string parameters.

@jclingan jclingan added this to the Future milestone Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants