-
Notifications
You must be signed in to change notification settings - Fork 19
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
Extend ResourceVisitor to hold parameters type information #11
base: master
Are you sure you want to change the base?
Conversation
…rameter and return result
@ibaca Here some general info what we are trying to accomplish:
But how to integrate autorest with gwt-jackson-apt without breaking the simplicity of autorest and while still keeping these two libraries unaware of each other?
One more change we got kind of as a "free bonus" as part of this pull request:
Turns out, once you do this, there is enough type information so that you can use your own response wrapper class, which might of course further return a collection of something etc. etc. Fully generified, but also completely backwards compatible with the original code that uses RxJava. |
Thanks for the PR and for this detailed explanation! The long-term solution I have in mind is a bit different. But as it might take some time to implement it I might merge this PR as a temporary solution. This will also ensure that when the final solution is implemented, it will support this use case. Question about the container. I strongly recommend using the concept of a container to reduce casuistics. I also discourage callback, so the container solves 2 things, 1. asynchronicity and 2. high-level transport type (empty response or command, single element, and many elements or stream). I know that you can return a scalar value directly but this is a pretty bad idea. Or you can generalize as you suggest. But, forcing you to differentiate the container might be more clear. Why just replace the second argument |
We would still be interested in an informal explanation of the long-term solution.
I don't think we are suggesting not to use a container. We just don't want to use the RxJava containers, that's all. However, the change of the signature of the 'as' method is not because we want to use a different container, but because of other reasons, see below.
No, we don't want to use "collection" and subtypes as the container. How would that work is actually beyond me. The main reason for using a container is because without it you can't really do an async call, can you? How would you be notified when the async result has arrived if you use a collection as a "container"? We'll just use our own, simple, custom container. User code wrapping it in an As for whether replacing just the second argument as
What gives? |
We are going to call those arguments the containerType and itemType. The goal of splitting is to encourage independent processing. I think this makes more sense in my mind that in the code 😉. But, for example maybe if we change the The second argument is associated with the final parsing of each item (the item might be a list). You might choose between a This is how I differentiate both containerType and itemType. Not sure that the explanation is clear enough 😬. But I really don't see both types of the same thing, and I think that the main problem is that both are just |
As already communicated, we can split them and it would still work, but I still fail to see the point. Two counter-arguments: Argument 1:
I'm trying to point out that the notions of transport (streaming or not), containerType and itemType are so closely interrelated that trying to differentiate them in the signature of method Argument 2 (actually a much stronger one): Here's a small use case that gets ugly with having the notion of "container" in the
OK but how is this at all an argument for or against having containerType and itemType vs a single "type"?
My Argument 2 from above applies here too. Why not keeping autorest a tad more generic so that it can be used without containers as well? Also important and I thought it is obvious: while you can get-by with a |
A small note: |
Hold on with this patch for a moment. We are working on the following changes:
|
Yep, I'm reading the gwt-jackson-apt issue. And actually, the I know it is possible to use proxies, note that autorest is like a subset of https://github.com/intendia-oss/qualifier/ (in this lib, the extension mechanism used at APT time and at runtime, is the one that I need to integrate into autorest and should make possible to solve this PR externally). And both qualifiers or autorest can be solved with proxies, as I say in the qualifier readme, if you can do that you should do that. BUT, AutoREST is focused in APT. If you want to do it using proxies, then just use Retrofit which is a pretty awesome library! Anyway, at a higher level, you can create a "proxy autorest" and we can share a "spec", but introducing the code and maintenance of a proxied based implementation is not really the goal of this lib. But a shared TCK might be a pretty nice solution if you end up implementing it. |
As for your |
- AutorestProxy - option to use j.l.r.Proxy instead of code generation for JavaSE/Android
…sor, fix several unit tests
Thanks to @ivmarkov, we have the patch completed. As he already highlighted, it includes
|
The I really think that you should create an issue or PR or at least move this discussion to gitter about the creation and usefulness of the |
How exactly is AutorestProxy limiting your ability to manage and deploy, given that it is in your "jre" project - which - by definition, is only useable in a proper JRE environment? Also, aren't we overdoing it by having another project (in addition to your "core", "jre", "processor" and "examples"), just to keep these ~ 200 lines of code separate? Also, why is the cross reference from "jre" to "processor" so bad? Annotation processors, and your "processor" too do run in a JRE environment anyway by definition. Also, where would you put the annotation-processing code which is shared by AutorestProxy and AutorestGwtPocessor? In another project of its own? Like, two additional projects now for < 1000 lines of code? Last but not least, what about the elephant in the room - the code in TypeToken then, which has JRE aspects (marked as @GwtIncompatible) as well as pure GWT aspects? The JRE aspects are necessary so that AutorestProxy (or even AutorestGwtProcessor - in a JRE environment) can interoperate with stuff like GSON or Jackson-proper, which do expect Java Reflection. Shall we somehow split TypeToken well, and how? (Please no offense!)... but this all seems to me a bit like a storm in a glass of water. AutorestGwt is a botique, miniature project. That's the beauty of it. It is so small, that everybody can immediately grasp how it works. Even after our contribution, I still believe this spirit is preserved. Yet, you treat it as if it is a huge codebase, used by thousands of users, where huge changes (our poor AutorestProxy!) are being introduced that require time to mature as a separate project, in a separate "organization" etc. etc. That's a bit too much work... not really sure it is worth the hassle, honestly... With that said, in the spirit of cooperation, and in the light of a constantly shrinking GWT community with a handful of projects used by just a few individuals who can't agree on basic stuff, e.g. look at GWT-React (12 stars) vs React4j (15 stars) here (a very unhealthy situation which is not giving me a warm fuzzy feeling for the future of GWT/J2CL - how about to you?), would the following modifications to the patch work for you:
We somehow maintain AutorestProxy privately, in our proprietary code base. We might or might not bother publishing these a few hundred lines of code to the open source. What do you say? |
Yep, I completely understand your point, but it is quite difficult to maintain and satisfy the requirement of every use case. What you describe as a warm-fuzzy-feeling might be also to accept those requirements and don't stick to the basics of the lib which make it solid. You can see this as just the opposite; libs are useful until features just destroy it (complexity), and at that point, someone creates a new lib from the start until features destroy the lib again. So, not an easy decision at all. Again, I really don't see any advantage in the proxy tool, even the name is not very appropriate, I name it AUTO bc of guava auto libs, which are related to annotation processor and how this outputs the boilerplate using APT that was previously created using proxies. Your project should be named ProxyRest or something like that. Also you think that using a common ResourceVisitor might be a good idea, but again this is against the whole idea of this library, this library makes it trivial to map services to request, but creating a nice request builder is NOT the purpose of this library, there are a lot of them and this library should delegate to those libraries (eg. RequestBuilder in GWT or jersey REST client in JRE, etc). I think that you are mixing "easy to do" with "should be doing". So the more you think the proxy is a good idea, the more I think you don't see the goal of this library. Proxy is an alternative to APT, and supporting both means common-denominator, and common-denominator means less flexibility. And, why you want to use the proxy implementation instead of the APT one? Even if this is true, what advantage it has to share the ResourceVisitor? Because if the advantage is too high, then I have done it badly, bc the ResourceVisitor should not be too clever the implementation, the goal is to make it easy to create your own clients with whatever library you choose. About the dependencies, or even the implementations itself. I personally, I would have omitted to publish the JRE and GWT modules, are just there to makes demos easier. And if you read the README, I encourage to create your own clients (so JRE and GWT clients are just reference implementations). This is the greatest discovery with this library, forcing you to make the implementation end up being much more simple and clear code. So, the processor module depending on a reference implementation module is a really bad idea. Any shared code should be moved to core, and the less code is in core the better. Anyway, at least you MUST create an independent PR for the ProxyVisitor, move it to a |
I don't think it is productive to continue arguing anymore on general topics. Instead, a summary of what we did:
If that's good enough for you in terms of code arrangement, would you please now spend some time reviewing the patch in details, including |
Hi @ibaca, I was wondering if it is possible to review the latest patch? Taking into account your considerations, I removed the AutorestProxy completely. |
Hi, sorry for the late response, I have been on holidays. Now it is easier to review, but I need some time. Also, I need to try it out combined with jackson-apt which I believe it is the practical goal of this PR. I need to find also some examples that justify the parameter type tokens. Thanks for your work and patience. |
Using autorest with external serializer/deserializer framework might be painful since there is no type information associated with REST methods parameters and return result. Thus, selecting appropriate serializer/deserializer require additional efforts. The problems become even bigger when using generic parameters/return result since we have to select serializer/deserializer not only for the generic type but for the type parameters as well.
Proposed changes affect the annotation processor and ResourceVisitor builder.
Newly created Type class is a recursive structure, that allows to model generic types and their corresponding classes;
ResourceVisitor interface is extended to receive type information associated with each REST method parameter and method return result;
Annotation processor inspects each REST method parameter and return result type and generate corresponding code to build Type object for the parameter or methods return result;