Hi,

Maybe I’m not getting something here.

A RESTful service is supposed to provide business entity oriented interfaces 
with CRUD like functionality. Tapestry provides front end oriented interfaces 
to support page views. There’s a huge difference in implementation.

GraphQL is more oriented towards supporting front end requirements.

John

Sent from my iPhone

> On 9 Oct 2021, at 05:12, Thiago H. de Paula Figueiredo <thiag...@gmail.com> 
> wrote:
> 
> I'm sorry, I forgot to include the logic for Swagger/OpenAPI message and
> configuration symbol lookups: Running the webapp with logging at debug
> level, you'll see entries from DefaultOpenApiDescriptionGenerator showing
> the message keys and configuration symbols being looked up.
> 
> 
>   - Everything is looked up by message first, configuration symbol second.
>   Symbols use the tapestry.[message key] format.
>      - Exception: openapi property is only looked up by symbol
>   - When building a message key, if it's based on a path, the starting
>   slash isn't removed.
>      - Example: openapi./something.head.summary
>   - When building a message key, HTTP method names are lowercased.
>   - openapi:
>      - tapestry.tapestry.openapi-application-version (no message lookup)
>   - info.title:
>      - tapestry.openapi-title
>   - info.description
>      - tapestry.openapi-description
>   - servers
>      1. BaseUrlSource.getBaseUrl(false) (base HTTP URL)
>      2. BaseUrlSource.getBaseUrl(true) (base HTTPS URL)
>   - tags. One tag automatically generated tags for each page:
>      - name:
>         1. openapi.[fully qualified class name].tag.name
>         2. openapi.[class name].tag.name
>         3. Class name (unchanged, not looked up)
>      - description:
>         1. openapi.[fully qualified class name].tag.description
>         2. openapi.[class name].tag.description
>      - Each page tag is automatically applied to all paths handled by the
>      page.
>   - paths property (REST endpoints). For each path:
>      - summary:
>      *openapi.[path].[HTTP method].summary
>      - description:
>      *openapi.[path].[HTTP method].summary
>      - responses. For each response:
>         - description
>            1. openapi.[path].[HTTP method].response.[HTTP status code]
>            2. openapi.[fully qualified class name].[HTTP
>            method].response.[HTTP status code]
>            3. openapi.[class name].[HTTP method].response.[HTTP status
>            code]
>            4. openapi.[HTTP method].response.[HTTP status code]
>            5. openapi.response.[HTTP status code]
> 
> 
>> On Fri, Oct 8, 2021 at 7:04 PM Thiago H. de Paula Figueiredo <
>> thiag...@gmail.com> wrote:
>> 
>> Hello, Tapestry community!
>> 
>> I've been working on something I really wanted Tapestry to have but
>> haven't had a chance to implement myself until some time ago: proper REST
>> support. And not do it by integrating with some other framework like Jersey
>> or CXF or by being a JAX-RS implementation, but by doing it in a very
>> Tapestry way: event handler methods, TypeCoercer for type conversions,
>> everything being customizable by contributions to Tapestry-IoC services,
>> return value of event handler methods handled by
>> ComponentEventResultProcessor implementations, etc.
>> 
>> This is a work in progress, done in the "rest" branch, so I decided to
>> publish a snapshot (5.8.0-SNAPSHOT) so you can use it yourself and tell me
>> what you feel about it. All feedback is welcome!
>> 
>> Major points:
>> 
>>   - New page-level events are triggered after the "activate" event is
>>   triggered (i.e. onActivate()) so you can write REST endpoints as regular,
>>   live-class-reloaded event handler methods.
>>      - One for each supported HTTP method: GET, POST, DELETE, PUT, HEAD,
>>      PATCH.
>>      - Event name is onHttp[method name]. For example, onHttpPut.
>>      - New constants in EventConstants for each supported HTTP method.
>>      - Activation context for REST event handler methods exactly in the
>>      same way as in onActivate().
>>      - Just like onActivate(), these new events are not triggered in
>>      components.
>>   - New service in tapestry-http (which is included by tapestry-core),
>>   RestSupport, with utility methods and <T> Optional<T>
>>   getRequestBodyAs(Class<T> type), which returns the request body converted
>>   to a given type.
>>      - getRequestAsBody(Class) uses HttpRequestBodyConverter.
>>   - Another new service in tapestry-http, HttpRequestBodyConverter,
>>   which uses an ordered configuration of itself, which provides conversions
>>   of request body to given types.
>>      - Only one method, <T> T convert(HttpServletRequest request,
>>      Class<T> type);
>>      - tapestry-http contributes one implementation, which is added as
>>      the last one in the ordered configuration, which uses TypeCoercer.
>>      - Out of the box, it supports conversions to String, primitive
>>      types, JSONArray, JSONObject plus any other type that has a String -> 
>> type
>>      conversion available in TypeCoercer, directly or not.
>>   - New annotation for page event handler method (onActivate(), onHttp*)
>>   parameters: @RequestBody, which receives the request body and converts it
>>   to the parameter type using RestSupport.getRequestAsBody().
>>   - Think of it as @RequestParameter but for the request body instead of
>>      a query parameter.
>>      - Example below.
>>   - New annotation for page event handler method (onActivate(), onHttp*)
>>   parameters: @StaticActivationContextValue("something"), for defining that
>>   method will only be called if that page activation context value matches a
>>   given string.
>>      - Example below.
>>      - Parameters with that annotation still get their values set as
>>      usual.
>>      - This was built mostly for REST support, but it can useful for
>>      non-REST situations too when a give activation context has a number of
>>      possible values and there's some logic tied to it.
>>   - Automatic generation of Swagger/OpenAPI 3.0 REST API definition
>>   files.
>>      - OpenApiDescriptionGenerator service, which is an ordered
>>      configuration of itself.
>>      - An internal implementation generates a base JSON object
>>      definition that can be customized by contributing more 
>> OpenApiDescription
>>      implementations.
>>      - Titles, names, summaries, etc can be provided by configuration
>>      symbols or message files (app.properties).
>>         - Messages files are live class reloaded too, so all changes
>>         done to the REST endpoint event handler methods and the corresponding
>>         messages are live reloaded.
>>         - Formats for message keys and described below.
>>      - Parameter descriptions not implemented yet.
>>         - It will support query parameters and path parameters.
>>      - [Not implemented yet] Embedded Swagger/OpenAPI viewer (i.e. the
>>   right pane of https://editor.swagger.io) hooked directly to the
>>   definition file generated by OpenApiDescriptionGenerator
>>      - It's going to be a separate subproject/JAR to avoid bloating
>>      projects not using the viewer
>> 
>> 
>> @StaticActivationContextValue example:
>> 
>>    final private String COMPLETED = "completed";
>>    final private String CLOSED = "closed";
>>    // Only called if first page activation context value is "completed"
>> 
>>    @OnEvent(EventConstants.ACTIVATE)
>>    void completed(@StaticActivationContextValue(COMPLETED) String state,
>> int id) {
>>        ...
>>    }
>> 
>>    // Only called if first page activation context value is "closed"
>>    @OnEvent(EventConstants.ACTIVATE)
>>    void closed(@StaticActivationContextValue(CLOSED) String state, int
>> id) {
>>        ...
>>    }
>> 
>> REST endpoint event handler method example:
>> 
>>    Object onHttpPatch(
>>            @StaticActivationContextValue("subpath") String subpath,
>>            String parameter,
>>            @RequestBody String body)
>>    {
>>        ...
>>    }
>> 
>>    @OnEvent(value = EventConstants.HTTP_DELETE)
>>    Object delete(@StaticActivationContextValue("subpath") String subpath,
>> String parameter)
>>    {
>>        return createResponse(EventConstants.HTTP_DELETE, null, parameter);
>>    }
>> 
>> Happy coding!
>> 
>> --
>> Thiago
>> 
> 
> 
> -- 
> Thiago

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org
For additional commands, e-mail: dev-h...@tapestry.apache.org

Reply via email to