Should matching be an array? If so how would you impl it? (it is associated
with "url" or another parameter for its config, for instance EXACT + path
so i don't see how it would work to support EXACT and WILDCARD at the same
time for ex).
In Request ensure to return Map<String, List<String>> and not
HashMap<String, String> (it is not a hashmap cause headers are case
insensitive for ex, a TreeMap(String.CASE_INSENSITIVE) is better IMHO but
no need to expose the impl).
Parameters should likely be split in body parameters (form data) and query
parameters (so getParameter(String) would be a facade to 2 get in query and
form maps).
Kind of the same remark on the response (for HashMap) + payload is an
InputStream. This one requires some explanation:

1. Using a ByteArrayOutputStream is quite limiting since you drop all
decorations and oversized payload support
2. An outputstream requires the server to know how to map this object to
something readable (input stream or the reactive equivalent)
3. output stream will likely require the server to inject the instance once
1 is fixed which is something we should try to avoid

Now if you move to an Inputstream you can consumer it easily from the
server point of view, wrap it easily (in a filter for ex) and setting the
output is as easy:

setOutput(new ByteArrayInputStream(...));
+ the user friendly flavor(s): setOutput(String) (which does the
setoutput(inputStream) + setHeader(content-length))

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le jeu. 18 juin 2020 à 14:58, Alexander Fischer <fische...@mailbox.org> a
écrit :

> Hey Romain,
>
> thanks for the feedback! I have implemented the API feedback now, please
> take another look:
> https://github.com/a-rekkusu/owb-centric-microserver
>
> Are there functionalities that you miss?
> Else, the Netty implementation ist next.
>
> Best regards,
> Alex
>
> On 16.06.2020 14:04, Romain Manni-Bucau wrote:
> > Hi Alex,
> >
> > I don't think you need the HttpHandler annotation to be a qualifier (will
> > typically end up on a method not producing any bean at some point I think
> > as in the example at the end of this answer).
> > I guess Request/Response models are not yet done? Side note before you
> work
> > on them: maybe don't copy servlet API, content-type, content-length etc
> are
> > just headers, no need to make them specific, also prefer to set the
> payload
> > (as an inputstream or reactive stream) rather than encapsulating
> read/write
> > methods, it enables a better composition and decoration in general and
> > bypasses to go through a provider/factory to create requests/responses.
> > Last thing is you probably want to create a package for that work and not
> > use the default one ;).
> >
> > Typically it is a good start IMHO and once this works I'd do another
> small
> > iteration to end up on:
> >
> > public class HelloWorldHandlerFuture
> > {
> > @HttpHandler(method = {HttpMethod.GET, HttpMethod.POST}, url = "/hello",
> > matching = Matching.EXACT)
> > public CompletionStage<Response> apply(Request request)
> > {
> > return CompletableFuture.supplyAsync(() ->
> > {
> > Response response = new Response();
> > response.setStatus(200);
> > response.write("Hello World from " + getClass().getName());
> > return response;
> > });
> > }
> > }
> >
> > Small side note (fully related to CompletionStage more than your current
> > work: if you want a synchronous impl of a CompletionStage you can use
> > CompletionFuture.completedFuture(response) - avoid the sypplyAsync - and
> if
> > you want to be async (sypplyAsync) ensure you pass an executor as second
> > parameter otherwise you end up being in default ForkJoinPool which has a
> > lot of side effects and limitations.
> >
> > Anyway, very good first iteration, it is pretty close to what I was
> > envisioning and it looks as smooth as I was thinking.
> >
> > Small tip for the impl phase (don't know if it is the next one or not):
> for
> > the handler registration, ensure to enable to do it programmatically:
> > register(Function<Request, CompletionStage<Response>>). It will enable to
> > use other models than the annotated one which is just a simplified API of
> > the actual one the server uses internally.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> > <https://rmannibucau.metawerx.net/> | Old Blog
> > <http://rmannibucau.wordpress.com> | Github <
> https://github.com/rmannibucau> |
> > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> > <
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >
> >
> >
> > Le mar. 16 juin 2020 à 13:08, Alexander Fischer <fische...@mailbox.org>
> a
> > écrit :
> >
> >> Hi Romain,
> >>
> >> I have made a first draft for the API and example showcase:
> >> https://github.com/a-rekkusu/owb-centric-microserver
> >>
> >> Please take a look and let me know what you think.
> >> CompletionStage is supported, but right now for all requests on a
> >> handler. If you would want a CompletableFuture only for POST for
> >> example, and not on GET, how do you think we should handle that?
> >> We could do it with a second HttpHandler on the same url but with the
> >> respective HttpMethod (e. g. HelloWorldHandlerGet /
> HelloWorldHandlerPost).
> >>
> >> Kind regards,
> >> Alex
> >>
> >> On 06.06.2020 15:44, Romain Manni-Bucau wrote:
> >>> Hi Alex,
> >>>
> >>> Nothing is written in the stone but here is how I would approach that:
> >>>
> >>> 1. Write a HTTP server able to call a handler to answer a request - you
> >> can
> >>> start by giving a hardcoded handler but in terms of design, ensure you
> >> get
> >>> something taking a Request abstracting as input and a Response
> >> abstraction
> >>> as output.
> >>> Netty has these abstraction but we don't want to depend on netty so you
> >>> should duplicate it making it even more user friendly (netty stays low
> >>> level).
> >>> 2. Make this server CDI friendly, basically a CDI bean and nice to
> have,
> >>> configurable (port, ssl, ...) with MP-Config (or equivalent - if you
> >> take a
> >>> Map<String, String> as input you won here),
> >>> 3. Now you have to abstract the handler and make the default handler a
> >>> facade for user handlers. User handlers are CDI beans. I would start by
> >>> making them with something between servlet and jaxrs:
> >>>
> >>> @HttpHandler(method = {GET, POST}, url = "/foo", mathing =
> >> Matching.EXACT)
> >>> method being the http method handled, url the urlpattern matched thanks
> >> the
> >>> matching algo (i used an enum but it can be anything equivalent). EXACT
> >>> means request path == url, we can envision wildcard matching (as in
> >>> servlet), regex matching etc...
> >>>
> >>> The signature can start to be the exact expected one
> >>> (CompletionStage<Response> onRequest(Request)) while validated in the
> cdi
> >>> extension grabbing the handlers, then you can relax the CompletionStage
> >>> requirement (Response onReq(Request)) and finally you can go closer to
> >>> jaxrs adding @PathParam/@QueryParam/... like annotations but if Request
> >> API
> >>> is nice enough it is not required in this layer - it can be a layer on
> >> top
> >>> as jaxrs is on top of servlet. What's important here is to be reactive
> >>> friendly by design - I'll let you play with the threading strategies to
> >>> have an useful CompletionStage and how to link it - or not ;) - to
> netty
> >>> executors.
> >>>
> >>> Once handlers well done, it is easy to add filters on top of it, same
> >> kind
> >>> of API but it takes another optional parameter:
> >>>
> >>> CompletionStage<Response> onRequest(Request request,
> >>> Supplier<CompletionStage<Response>> proceed);
> >>>
> >>> with proceed the call to filter N+1 and finally the handler (check out
> >> OWB
> >>> interceptor impl, it is exactly the same.
> >>>
> >>> Last important point: ensure to handle @Priority (or add priority = int
> >>> in @HttpHandler) cause when you will implement the matching chain you
> >> will
> >>> need an order normally.
> >>>
> >>> Bonus: you can make the matching strategies pluggable if you want and
> >> just
> >>> provide some defaults OOTB.
> >>>
> >>> Hope it makes sense.
> >>>
> >>> Romain Manni-Bucau
> >>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> >>> <https://rmannibucau.metawerx.net/> | Old Blog
> >>> <http://rmannibucau.wordpress.com> | Github <
> >> https://github.com/rmannibucau> |
> >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> >>> <
> >>
> https://www.packtpub.com/application-development/java-ee-8-high-performance
> >>>
> >>>
> >>> Le jeu. 4 juin 2020 à 15:35, Alexander Fischer <fische...@mailbox.org>
> a
> >>> écrit :
> >>>
> >>>> Hello everyone,
> >>>>
> >>>> in the last month I have spent most of my time getting to know coding
> >>>> basics of Maven, Netty, CDI/OWB and Servlets/Tomcat. I got to know CDI
> >>>> extensions which will be the technological foundation for the server.
> >>>>
> >>>> Next up will be defining and implementing the HTTP API, which will
> bring
> >>>> CDI and Netty together. Feel free to contribute your thoughts on the
> >>>> matter here on the mailing list or in the respective Jira issue:
> >>>> https://issues.apache.org/jira/projects/OWB/issues/OWB-1319
> >>>>
> >>>> @Romain: can you share some ideas, annotations, interfaces for how you
> >>>> see the API roughly? Any kind of formal requirement-proposal would be
> >>>> helpful to start with.
> >>>>
> >>>> Thanks and best regards,
> >>>> Alexander
> >>>>
> >>>>
>

Reply via email to