Hi Romain,

you are right with your points and I've tried to apply them. The
Request.parameters() method might be solvable more elegantly. Only
streams were a bit unclear to me, but I did it as I understood it for
now (correct me if I got it wrong):
the user writes/casts his intended output to a ByteArrayInputStream,
which is handed over to netty that transforms it to its actual output
(maybe ChannelBufferOutputStream, but I have yet to figure it out).
Let me know what you think of the current state, please. Once again the
repo link, just for convenience.
https://github.com/a-rekkusu/owb-centric-microserver

Thanks and best regards,
Alex

On 18.06.2020 15:26, Romain Manni-Bucau wrote:
> 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