Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <3SGdnTa9B72zt777nZ2dnZfqnPWdnZ2d@giganews.com>
Deutsch   English   Français   Italiano  
<3SGdnTa9B72zt777nZ2dnZfqnPWdnZ2d@giganews.com>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!Xl.tags.giganews.com!local-2.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Sat, 20 Apr 2024 02:36:29 +0000
Subject: Re: Java HTTP API Signatures, schemas, XML and JSON, Pojo's and
 Poji's, Java and Spring and schema
Newsgroups: comp.lang.java.programmer
References: <2imdnULqbvFsBr_7nZ2dnZfqn_qdnZ2d@giganews.com>
 <WqWdnZlV5tCGNb_7nZ2dnZfqnPSdnZ2d@giganews.com>
 <q4idnSKRjoEVIb_7nZ2dnZfqn_adnZ2d@giganews.com>
 <S3ednfNU6sAbRb_7nZ2dnZfqnPqdnZ2d@giganews.com>
From: Ross Finlayson <ross.a.finlayson@gmail.com>
Date: Fri, 19 Apr 2024 19:37:31 -0700
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101
 Thunderbird/38.6.0
MIME-Version: 1.0
In-Reply-To: <S3ednfNU6sAbRb_7nZ2dnZfqnPqdnZ2d@giganews.com>
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Message-ID: <3SGdnTa9B72zt777nZ2dnZfqnPWdnZ2d@giganews.com>
Lines: 1263
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-Lx02+T2j3FMNApFfNzL4rxgyVg0dj6LHRdcFCt/9GO2ZqYqx6ibEatFqaym5VkDCh+LDC6vQ3QTWDvk!/xVPIvlk2COpqvz02QR/PFj2s0FRtSbOk1fEompT1EGAwIvmOPVIF8CRjaEoQWuP2zqnUOSs+YsC!tw==
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
Bytes: 52805

On 04/19/2024 01:48 PM, Ross Finlayson wrote:
> On 04/19/2024 11:49 AM, Ross Finlayson wrote:
>> On 04/19/2024 10:22 AM, Ross Finlayson wrote:
>>> On 04/19/2024 09:30 AM, Ross Finlayson wrote:
>>>> Signature API
>>>>
>>>> ccc.api
>>>> ccc.api.exception
>>>> ccc.api.fault
>>>>
>>>> ccc.api.client
>>>>
>>>> ccc.springsup.web
>>>>
>>>> ccc.serdes
>>>>
>>>>
>>>> Api ApiMapping
>>>>
>>>> ApiFlt ApiHardFlt
>>>> OtherCauseFault CovariantFault
>>>>
>>>> Pth Hdr Qpa Req Rsp Flt Err
>>>>
>>>>
>>>> The other day I was writing a Spring Boot server,
>>>> and the implementation of the Api looks like this
>>>>
>>>> For a service Srv, group of APIs Grp, and API Api
>>>>
>>>> public interface Srv {
>>>>      interface Grp {
>>>>          interface Api extends ccc.api.Api {
>>>>
>>>>              static class Pth{}
>>>>              static class Qpa{}
>>>>              static class Hdr{}
>>>>              static class Req{}
>>>>              static class Rsp{}
>>>>              static class Flt{}
>>>>              static class Err{}
>>>>
>>>>
>>>>              Rsp api(
>>>>                  @Valid @NotNull Pth pth,
>>>>                  @Valid @NotNull Qpa qpa,
>>>>                  @Valid @NotNull Hdr hdr,
>>>>                  @Valid @NotNull Req req
>>>>              ) throws ApiFlt;
>>>>
>>>>          }
>>>>      }
>>>>
>>>> }
>>>>
>>>> The validation annotations have to be on the root type,
>>>> so, they go on the Api.
>>>>
>>>> public interface SrvMapping {
>>>>      interface Grp {
>>>>          @RequestMapping
>>>>          interface Api extends Srv.Grp.Api, ApiMapping {
>>>>
>>>>              @Override
>>>>              @GetMapping("/api/{pth}")
>>>>              @ResponseBody
>>>>              Rsp api(
>>>>                  @PathVariable Pth pth,
>>>>                  @QueryParam Qpa qpa,
>>>>                  @RequestHeader Hdr hdr,
>>>>                  @RequestBody Req req
>>>>              ) throws ApiFlt;
>>>>
>>>>          }
>>>>      }
>>>> }
>>>>
>>>> The request mapping and also the openapi or documentation
>>>> interfaces have to be on the interface the controller implements,
>>>> and they don't mean anything to the Api, so they go on the ApiMapping.
>>>>
>>>> @Controller
>>>> public class SrvController implements SrvMapping.Grp.Api
>>>> {
>>>>              @Override
>>>>              Srv.Grp.Rsp api(
>>>>                  Srv.Grp.Pth pth,
>>>>                  Srv.Grp.Qpa qpa,
>>>>                  Srv.Grp.Hdr hdr,
>>>>                  Srv.Grp.Req req
>>>>              ) throws ApiFlt;
>>>> }
>>>>
>>>> The controller just implements the Api, Spring Web wires
>>>> it up and Openapi documents it up.
>>>>
>>>> And it results sort of thusly a very simple organization of APIs.
>>>>
>>>> public interface Srv {
>>>>
>>>>      interface Grp1 {
>>>>          interface Api1 { /* */ }
>>>>          interface Api2 { /* */ }
>>>>          interface Api3 { /* */ }
>>>>          interface Api4 { /* */ }
>>>>      }
>>>>      interface Grp@ {
>>>>          interface Api1 { /* */ }
>>>>          interface Api2 { /* */ }
>>>>          interface Api3 { /* */ }
>>>>          interface Api4 { /* */ }
>>>>      }
>>>>      /* */
>>>> }
>>>>
>>>> The key is that given those, the Api and ApiMapping an entire
>>>> Signature, of the mapping, sort of results, with adding this
>>>> sort of ApiStatusMapping, to relate the HTTP status codes,
>>>> with, the covariant return bodies, then it's sort of all one thing.
>>>>
>>>> ("a functional interface may still have multiple default methods ...")
>>>>
>>>> The idea is that the interfaces carry very well down from these.
>>>>
>>>> For most often usual "APIs" these days it'd often look:
>>>>
>>>> @Data
>>>> static class MyGrp {
>>>>
>>>> }
>>>>
>>>> public interface Srv {
>>>>      interface Grp {
>>>>          interface Get1 extends ccc.api.Api {
>>>>
>>>>              static class Pth{ String myGrpId;}
>>>>              static class Req extends MyGrp{};
>>>>              static class Rsp{}
>>>>              static class Flt{}
>>>>              static class Err{}
>>>>
>>>>              Rsp get1(
>>>>                  @Valid @NotNull Pth pth,
>>>>                  @Valid @NotNull Req req
>>>>              ) throws ApiFlt;
>>>>
>>>>          }
>>>>          interface Put1 extends ccc.api.Api {
>>>>
>>>>              static class Pth{ String myGrpId;}
>>>>              static class Req extends MyGrp{}
>>>>              static class Rsp{}
>>>>              static class Flt{}
>>>>              static class Err{}
>>>>
>>>>              Rsp put1(
>>>>                  @Valid @NotNull Pth pth,
>>>>                  @Valid @NotNull Req req
>>>>              ) throws ApiFlt;
>>>>
>>>>          }
>>>>      }
>>>>
>>>> }
>>>>
>>>>
>>>> public interface SrvMapping {
>>>>      interface Grp {
>>>>          @RequestMapping
>>>>          interface Api extends Srv.Grp.Get1, ApiMapping {
>>>>
>>>>              @Override
========== REMAINDER OF ARTICLE TRUNCATED ==========