juneau-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Bognar <james.bog...@salesforce.com>
Subject Re: Advice regarding Juneau RestClient, RestCall, Serializers, best practices
Date Wed, 22 Mar 2017 16:17:28 GMT
*This makes a lot of sense to me.  If it’s possible to also allow for an
in-line override of Serializer or Parser, that would limit the number of
RestClients our provider classes need to create (to 1).*

Will do.


*And you can also specify arrays...getResponse(MyBean[].class). This is
perfect.  I remember now seeing the Type,Type… method in the release notes
and will try it out right away.  Of course, I’m hoping that RemoteableProxy
can be used across the board, if so we won’t need implementation classes
that would have to do this at all.*

I need to update the javadocs on the RestClient.getResponse(Type,Type...)
method.  It's not clear from the docs how to use it.  For now, just refer
to the Parser#parse(Type,Type...) for how that works for maps and
collections.

If you're interested in the remoteable proxies, you'll probably be
interested in what I've been working on this week...adding interface
proxies using @RestMethod.  It's a simplified way to define them without
having to use the RemoteableServlet.  Instead, you just define a
@RestMethod(name="PROXY") method with an interface return type, like so....

/**
* [PROXY /*]
* Return a proxy interface to IAddressBook.
*/
@RestMethod(name="PROXY", path="/myproxy/*")
public IAddressBook getProxy() {
   return addressBook;
}
On the client side, you get the proxy using RestClient like so....

IAddressBook ab = client.getRemoteableProxy(IAddressBook.class,
"/addressBook/myproxy");
Under-the-covers, a method call is simply a POST with parameters and
returned object marshalled in the HTTP request and response bodies, and the
individual methods are addressed using the method signature...e.g....
POST /addressBook/myproxy/callMyMethod(java.lang.String,boolean)







On Wed, Mar 22, 2017 at 11:20 AM, sblackmon <sblackmon@apache.org> wrote:

> Thanks James.  Comments below.
> On March 20, 2017 at 11:48:16 AM, James Bognar (
> james.bognar@salesforce.com) wrote:
>
> Hi Steve!
>
> I'm in training today, so my responses may not be prompt.
>
> Heads up....in 6.2.0 (what I'm working on now, currently labeled 6.1.1),
> I'm revamping the RestClient code to use builders just like I did for the
> serializers and parsers in 6.1.0. So now's a good time for suggested
> changes! I think the new design makes it considerably easier to understand
> and reuse HttpClients or HttpClientBuilders.
>
> You're correct that a RestClient only uses a single serializer/parser
> pair. The thoughts were...
> 1) You avoid having to specify the Accept and Content-Type on the RestCall
> object.
> 2) Typical real-world scenario would be that you're only interested in
> working in a particular language.
>
> If you anticipate needing support for multiple languages, it won't be
> difficult to add. Most likely with a 'default' language, and if you want
> to use one of the others, you need to do...
> RestClient.doX().setAccept("text/foo").setContentType("
> text/foo").getResponse(X);
>
> Let me know if you want this.
> This makes a lot of sense to me.  If it’s possible to also allow for an
> in-line override of Serializer or Parser, that would limit the number of
> RestClients our provider classes need to create (to 1).
>
>
>
> *I also am thinking that a new method on RestClient that allowed you to
> doGet from an request POJO, and have it converted into parameters (using
> BeanMap?) would help make this easier.*
> I'm not sure I understand. Can you provide a code example? (or is it in
> the branch already?)
> Here’s a specific use case from STREAMS-496.
>
> We have an interface that describes the behavior of an external REST
> endpoint:
>
> https://github.com/steveblackmon/incubator-streams/blob/STREAMS-496/
> streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/
> twitter/api/Statuses.java
>
> The module contains POJOs for the inputs and outputs of these endpoints,
> generate from jsonschemas.
>
> https://github.com/steveblackmon/incubator-streams/blob/STREAMS-496/
> streams-contrib/streams-provider-twitter/src/main/
> jsonschema/org/apache/streams/twitter/api/StatusesLookupRequest.json
>
> As I understand, If the third-party endpoints worked on the ‘post with
> json to get json’ model, then we could use juneau’s RemotableProxy
> capability to execute these transactions with just the POJOs and the
> interface, no implementation of the interface required!  Very cool...
> However, the third-party endpoints actually use a ‘get with a bunch of
> params to get json’ model, and defining the interface methods as a chain of
> 10+ primitives, most of which are optional, is ugly and difficult to use in
> java.  I’d much prefer to define the interface using a ‘one POJO in, one
> POJO out’ (like in the links above), and use the fluent builders on those
> beans to craft the request objects.
>
> My suggestion is to add a generic swap capability usable by RestClient or
> RemoteableProxy that can translate a single (probably flat) POJO argument
> into get parameters transparently, so that remotableproxy using get
> requests with complex argument structures can be as easy to code and easy
> to read as those using post requests with payloads.
>
> If this sounds good to you, put it in JIRA and I’ll take a shot at the
> implementation.
>
>
>
> *Also wondering whether type erasure will limit the flexibility of
> restCall.getResponse(T), when the result comes back as a List. In my own
> APIs I always return an Object but a top-level array is fairly common
> practice.*
>
> The getResponse(Type,Type...) method should allow you to reconstruct
> parameterized lists and maps.
> For example:
> getResponse(LinkedList.class,MyBean.class) - A list of beans.
> getResponse(HashMap.class,String.class,LinkedList.class,MyBean.class) - A
> hashmap with string keys and list of beans values.
>
> And you can also specify arrays...getResponse(MyBean[].class).
> This is perfect.  I remember now seeing the Type,Type… method in the
> release notes and will try it out right away.  Of course, I’m hoping that
> RemoteableProxy can be used across the board, if so we won’t need
> implementation classes that would have to do this at all.
>
>
>
> Refer to the Parser#parse(Object input, Type type, Type...args) javadocs
> for info. The RestCall#getResponse() should act the same.
>
>
>
> On Mon, Mar 20, 2017 at 2:55 AM, sblackmon <sblackmon@apache.org> wrote:
>
> > Hello,
> >
> > I’m working on a class that uses RestClient to implement several
> > contextually related methods.
> >
> > Each method has a POJO describing the request, and a POJO describing the
> > response (some methods return a list of the response POJOs).
> >
> > As I understand from reading docs for 6.1.1-incubating-SNAPSHOT, while a
> > RestServlet may bind multiple Serializers and Parsers, a RestClient may
> > only bind one of each.
> >
> > So i guess that means I need to instantiate a different RestClient for
> > each supported method, or bind a single custom Serializer and Parser
> that
> > can handle all of the request and response objects?
> >
> > I notice that it’s easy to create and re-use one HttpClient across
> > RestClients, and there’s presumably no problem reusing all the member
> > objects of RestClient, so there should be minimal performance overhead
> to
> > holding more than one on the class, or even creating a new RestClient
> for
> > every call is I don’t close the connection.
> >
> > I also am thinking that a new method on RestClient that allowed you to
> > doGet from an request POJO, and have it converted into parameters (using
> > BeanMap?) would help make this easier.
> >
> > Also wondering whether type erasure will limit the flexibility of
> > restCall.getResponse(T), when the result comes back as a List. In my own
> > APIs I always return an Object but a top-level array is fairly common
> > practice.
> >
> > Anyway, I’ve pushed some early work to this branch, and I’d be
> interested
> > in feedback as I work through this, whether it’s on the right track to
> > minimize code complexity and maximize performance for what we’re trying
> to
> > do.
> >
> > I’m not yet to the point of running any integration tests using this new
> > implementation but hope to be soon.
> >
> > https://github.com/apache/incubator-streams/compare/
> > master...steveblackmon:STREAMS-496
> >
> > Thanks in advance,
> > Steve (Streams)
>
>
>
>
> --
> James Bognar
>



-- 
James Bognar

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message