Payaraã§OpenAPI(MicroProfile)
ã¯ããã«
Payaraã§OpenAPI-UIãã¤ãã£ã¦ãWebAPIã®ä»æ§ã¨å®è¡ã¤ã³ã¿ã¼ãã§ã¼ã¹ãæºåããå®è£
ã§ãã
軽ã触ã£ã¦ã¿ãæãã®å®è£
ä¾ããQuarkusï¼MicroProfileã®å®è£
ï¼ã使ã£ããã®ã¯ãã£ãã®ã§ããæ¨æºä»æ§ã ãã®ç¯çã ãã§ã§ãããã®ã¯ãªããªãè¦ã¤ãããªãã£ãã®ã§è²ã
ã¨è©¦ããªãããã£ã¦ãã£ã¦ã¿ã¾ããã
ã¡ã¤ã³ãOpenAPIã«ããã®ã§JAX-RSï¼Jakarta RESTful Web Servicesï¼ã«ã¤ãã¦ã®èª¬æã¯å²æãã¾ãã
- ã¯ããã«
- å®è¡ç°å¢
- ãã£ã¦ã¿ã¦æã£ããã¨ã»ããã£ããã¨
- OpenAPIã®è¨è¿°ã¯å®è£ ãããåªå
- ã¢ããã¼ã·ã§ã³ã§åºæ¥ãªãã¨ãã¯ã³ã¼ãã§ä½ãè¾¼ã¿
- OpenAPIã®è¨è¿°ã¨å®è¡è¨è¿°ã¯åãã¦ãããã
- tagãã¤ãã£ã¦ã³ã³ããã¼ã©ã¼åä½ã§éç´
- ã¬ã¹ãã³ã¹ã®åã¯Genericã使ããªãããã«ç´°ããä½æ
- @ExampleObjectãã¡ããã¨æ¸ã
- ãã©ã¡ã¼ã¿ã®è¨è¼ã¯ @Parameters ã使ã
- OpenAPI yamlã§ã®åºåããéç®ãã¦èãã
- pom
- Responseã®æ§é ä½
- GET
- POST
- PUT
- DELETE
- ãã¡ã¤ã«ã¢ãããã¼ã
- Enumã®ãªã¹ããã¯ã¨ãªãã©ã¡ã¼ã¿
- Exceptionï¼2xx系以å¤ã®ã¹ãã¼ã¿ã¹ï¼
- Code
- åè
- ãããã«
å®è¡ç°å¢
ãã£ã¦ã¿ã¦æã£ããã¨ã»ããã£ããã¨
å®éã«ãã£ã¦ã¿ã¦æã£ããã¨ãªã©ãå
ã«ã
ã©ããã¦ãããªã£ã¦ããã®ï¼ã¨ããã®ãåãã£ã¦ããã¨ä»¥ä¸ã®ã³ã¼ãã®çç±ãåãããããããã«æã£ãã®ã§ã
OpenAPIã®è¨è¿°ã¯å®è£ ãããåªå
å®è£
ããããç¨åº¦èªåçæã¯ããã¾ããã
OpenAPIã®è¨è¿°ã®æ¹ãåªå
ãããã®ã§OpenAPI-UIã§ã¤ããã¤ã³ã¿ã¼ãã§ã¼ã¹ã®ä½ãè¾¼ã¿ã¯èªåã§ã³ãã³ãæ¸ãè¾¼ãæ¹ã¨å²ãåã£ãæ¹ãè¯ãããã§ãã
ä¾ãã°Enumã¯ã©ã¹ã¯Enumã®è¦ç´ ã enumeration
ã§åæããã®ãåºæ¬ã¨ãªãã¿ããã§ããã¡ãã£ã¨é¢åã§ããâ¦ã
ã¡ãªã¿ã« @BeanParam
ã§å®ç¾©ãããã®ã¯ããã®ã¾ã¾ã§ã¯ã©ããã£ã¦ãOpenAPI-UIã§ä½¿ããªãã®ã§ãããOpenAPIã®è¨è¿°ãå®è£
ãããåªå
ããããã¨ã§ä½ãè¾¼ããã¨ãã§ãã¾ã*1ã
ã¢ããã¼ã·ã§ã³ã§åºæ¥ãªãã¨ãã¯ã³ã¼ãã§ä½ãè¾¼ã¿
ãªã¹ãã®ã¯ã¨ãªãã©ã¡ã¼ã¿ã¯ã¢ããã¼ã·ã§ã³ã§ã¯å®ç¾åºæ¥ã¾ããã§ããã
ãããªã¨ã㯠OASModelReader
ã®å®è£
ã®ä¸ã§ OASFactory.createComponents()
ãã¤ãã£ã¦ã³ã¼ãã§ä½ãè¾¼ãã¨å®ç¾ã§ãããã¨ãããã¾ãã
ã¢ããã¼ã·ã§ã³ã§é å¼µã£ã¦ä¸æããããªãã¨ãã¯å²ãåã£ã¦ã³ã¼ããæ¸ãã®ãä¸æ¡ã§ãã
ã¡ãªã¿ã«ãä¸è¨ã®ãEnumã¯enumeration
ã®åæãã§ãããã³ã¼ãã§ã¹ãã¼ããå®ç¾©ããã°å
±éåã§ãã¾ãã
OpenAPIã®è¨è¿°ã¨å®è¡è¨è¿°ã¯åãã¦ãããã
ã¡ã½ããã®å¼æ°ã«@Parameter
ãä»ããæ¹æ³ãããã¾ãããå人çã«ã¯ã¡ã½ããã¢ããã¼ã·ã§ã³ã«å¯ããæ¹ãã³ã¼ããèªã¿ãããããªã¨æãã¾ãã
ã¤ã¡ã¼ã¸ã¨ãã¦ã¯RESTfulã®å®è£
ãããä¸ã§ããã®ã³ã¼ãé¨åã«ã¯æãå ããã«ã¡ã½ããã¢ããã¼ã·ã§ã³ã§æ
å ±ãä»ä¸ããã¨ããæµãã§æ¸ã足ããæ¹ã好ã¿ã§ãã
ä»®å¼æ°ã®ä¸ã«è¤éãªã¢ããã¼ã·ã§ã³ãè¨è¿°ãã¦ããã¨ãã³ã¼ãã®å¼æ°ãã©ãã«ããã®ãè¦èªæ§ãæªããªãã¨ããã®ãçç±ã§ãã
ãã ãããã¾ãããããæ¸ãæ¹ãæ¨å¥¨ããã¨ããæ
å ±ãç¡ãã£ãã®ã§çéã§ã¯ãªããããããªãã§ãã
tagãã¤ãã£ã¦ã³ã³ããã¼ã©ã¼åä½ã§éç´
tagã使ãã®URLãã¾ã¨ãããã¨ãåºæ¥ã¾ãã
以åãSpringBoot & springdoc-openapi ã使ã£ãæã¯tagã使ããªãã£ãã®ã§å
¨é¨ããã©ããã«ãªã£ã¦ããã¥ã¡ã³ãã¨ãã¦ã®è¦èªæ§ãæªãã£ãããã«æãã¾ãã
ãªããtagãè¤æ°ä»ä¸ããã¨tagã®åã ãåãURLãåãOpenAPI-UIã«è¡¨ç¤ºããã¾ãã
OpenAPIã®å®ç¾©ãDSLã¨ãã¦ããã«èªåçæãããã¨ãä¸å
·åã«ç¹ãããããããªãã®ã§è¤æ°tagãä»ä¸ããã¨ãã¯ããã®å
ãå«ãã¦äºåã«æè¡æ¤è¨¼ããã¦ãããã¨ããããããã¾ãã
ã¬ã¹ãã³ã¹ã®åã¯Genericã使ããªãããã«ç´°ããä½æ
@Schema(implementation = Hoge.class)
ã¿ããã«è¨è¿°ãããã¨ã§ã¬ã¹ãã³ã¹ã®åã®æå®ãã§ããã®ã§ããGenericã使ãã¾ããã
ãªã®ã§ãã¬ã¹ãã³ã¹ã¯ã©ã¹ã代表ã¨ãã¦ããã®æ´¾çã¯ã©ã¹ãã¤ã³ãã¼ã¯ã©ã¹ã¨ãã¦å®ç¾©ãã¾ããã
public class UserResponse extends UserRequest { ï¼ç¥ï¼ static class UserResponseBody extends ResponseBody<UserResponse> {} }
@ExampleObjectãã¡ããã¨æ¸ã
Genericã使ããªããã°åæ
å ±ããããç¨åº¦ã¯OpenAPI-UIã§è¡¨ç¤ºå¯è½ãªå®ç¾©ãå®è£
ããèªåçæãã¦ããã¾ãã
ãã ä»å㯠ResponseBody
ã¨ããå
±éå®ç¾©ã«ã¬ã¹ãã³ã¹ãGenericã§å®ç¾©ãã¦å
¥ãåæ§é ãªæãã«ããã®ã§ããã®ãããã¯èªåã§ã¯ã§ãã*2ã
ãªã¯ã¨ã¹ãã¯å
¥ãåæ§é ã«ããªãã£ãã®ã§ãããObjectåï¼ä¾ãã°Enumï¼ã使ã£ããããã¨ãexampleãæã£ãããã«åºåãããªãã£ãã®ã§ããã¡ããã³ãã³ãå®ç¾©ãã¾ããã
ã¬ã¹ãã³ã¹ã¯ã¨ããããæ¡ä»¶ãæå®ãã¦å®éã«åºåãããã°exampleãç¡ãã¦ãææªãªãã¨ãã§ããªãã¯ãªãã®ã§ããããªã¯ã¨ã¹ãã¯POSTãPUTãããã¨ãã«OpenAPI-UIã§ä½¿ãããã®ã§æéãããã£ãã¨ãã¦ãããã¡ãã¨è¨è¿°ãããã¨ããå§ããã¾ãã
@ExampleObject
ãè¨è¿°ããã¨ãã®çæäºé
ã¨ãã¦
- MediaTypeãæãã
- nameãexampleã®ãã¼ã«ãªãã®ã§è¨è¿°ãå¿ããªã
ã¨ããã®ãããã£ãã¨ããã§ããã
ãã©ã¡ã¼ã¿ã®è¨è¼ã¯ @Parameters
ã使ã
å¼æ°ã§ã¯ãªãã¡ã½ããã«ãã©ã¡ã¼ã¿ãæå®ããå ´åããã©ã¡ã¼ã¿ãï¼ã¤ã®å ´åã§ãã@Parameters
ã使ããªãã¨OpenAPIã®åºåã¨ãã¦æ
å ±ãåºåããã¾ããã§ããã
OpenAPI yamlã§ã®åºåããéç®ãã¦èãã
ä¾ãã°ããã¡ã¤ã«ã¢ãããã¼ãã®æ¸ãæ¹ã«ã¤ãã¦ã¢ããã¼ã·ã§ã³ãã³ã¼ãã§ã®å®ç¾©æ¹æ³ãæ¢ãã¦ããã«è¦ã¤ãããªãå ´åã¯ãæçµçãªOpenAPIã®yamlã§ã®æ¸ãæ¹ã調ã¹ã¦ãããããããã©ããã£ããã¢ããã¼ã·ã§ã³ãããã¯ã³ã¼ãã§å®ç¾©ã§ããã®ãï¼ã¨ããã®ãéå¼ãã§çµã¿ç«ã¦ãã¨ã¹ã ã¼ãºã«è©¦è¡ãé²ãããã¾ããã
ä»åã®å®è£
ã§ããã¨
- Enumãæ¤ç´¢ç¨ã¯ã¨ãªã¨ãã¦ãªã¹ãã«ããã
- è¤æ°ãã¡ã¤ã«ã®ã¢ãããã¼ãã®è¨å®ã®ããæ¹
ããéå¼ãããè¦ã¤ããããå®ç¾©ã§ããã
pom
OpenAPI-UIã使ãããã®ã©ã¤ãã©ãªã
ããããªãã¨OpenAPI-UIã®ãã¼ã¸ãä½ãããªãã§ãã
<dependency> <groupId>org.microprofile-ext.openapi-ext</groupId> <artifactId>openapi-ui</artifactId> <version>2.1.0</version> </dependency>
ããã¦
http://localhost:8080/ee10-01-openapi/api/openapi-ui/index.html
ã¿ãããªæãã§ãã¢ããªã®ã«ã¼ããããopenapi-ui/index.htmlãã¸ã¢ã¯ã»ã¹ãããã¨OpenAPI-UIã®ç»é¢ã表示ããã¾ãã
ã¾ãã以ä¸ã«ã¢ã¯ã»ã¹ããã㨠OpenAPIã®å®ç¾©ï¼ãã¡ãã¯Payaraã®å®è£
ãä½æãã¦ãããã®ï¼ã確èªãããã¨ãã§ãã¾ãã
ãªã®ã§ãèªåãæå³ããç»é¢è¡¨ç¤ºãã§ãã¦ããªãã¨ãã¯ããã¡ãã確èªã㦠ã©ãããå®ç¾©ã«ãªãã°è¯ãã®ã確èªãããªããä½æ¥ãé²ãããã¨ã«ãªãã¾ãã
[http://localhost:8080/openapi]
Responseã®æ§é ä½
ã¾ãã¯Responseã®æ§é ä½ããã
å
±éã®æ§é ä½ãã©ãããããã®ãã¬ã¹ãã³ã¹ããããã«ãããã¨æãã¾ãã
ããã³ãã§HTTPã¹ãã¼ã¿ã¹ã§å¤å®ãããã®ãè¯ãã§ãããæ£å¸¸ç°å¸¸ãifæã§åãããã¨ããããããä»å æ
å ±ãè¨ãããã±ã¼ã¹ãæ³å®ãããã®ã§ãã
ãã¡ãããå
±éã¯ã©ã¹ãextendããããæ¹ã§ãè¯ãã¨æãã¾ãã
@Schema public class BaseResponseBody { @Schema(title = "ã¬ã¹ãã³ã¹æå¦", description = "æ£å¸¸ã®å ´åã¯true", readOnly = true) boolean ok;
@Schema public class ResponseBody<T> extends BaseResponseBody { @Schema(title = "ã¬ã¹ãã³ã¹ããã£", description = "ã¬ã¹ãã³ã¹æ¯ã®ç¬èªã®åã®ãªãã¸ã§ã¯ã", readOnly = true) private T body; ï¼getter setter ä»ã¯çç¥ï¼
ãªã¹ãæ§é ã®å ´åã¯ãã¡ãã使ãã¾ãã
@Schema public class ResponseListBody<T> extends BaseResponseBody { @Schema(title = "ã¬ã¹ãã³ã¹ããã£", description = "ã¬ã¹ãã³ã¹æ¯ã®ç¬èªã®åã®ãªãã¸ã§ã¯ã", readOnly = true) private List<T> body; public ResponseListBody() {} ï¼getter setter ä»ã¯çç¥ï¼
ãããä»ä¸ããããã®Factoryã使ã£ã¦Responseãã¤ããã¨ããæµãã§ãã
ã¡ãªã¿ã« GenericEntity
ã使ã£ã¦ãã¾ãããå¤å使ããªãã¦ãçµæã¯åããããªãããªï¼ã¨æãã¾ã*3ã
public static <T> Response success(T body) { var entity = new ResponseBody<T>(true, body); var responseBuilder = Response.ok(new GenericEntity<ResponseBody<T>>(entity) {}); return responseBuilder.build(); }
GET
ã·ã³ãã«ãªãã¹ã¢ã¯ã»ã¹
ä¸çªã·ã³ãã«ãªè¨è¼ã¯ãããªæãã§ãã
ããã§ãã¤ã³ãã«ãªãã®ã¯ã¬ã¹ãã³ã¹ã®åã®æå®ã¨ãã®å®è£
ã§ãã
static class UserResponseBody extends ResponseBody<UserResponse> {}
ã¨ããæãã§ãOpenAPIç¨ã«åã¯ã©ã¹ãä½ã£ã¦ããããæå®ãã¾ãã
å¿è«ãã¹ãã¼ããåå¥ã«å®ç¾©ããæ¹æ³ãããã¾ãããOASModelReader
ã«è¨è¼ããå¿
è¦ãããã®ã¨æååã§ã®æå®ã«ãªãã®ã§ã¯ã©ã¹è¨è¿°ã§å¯¾å¿ã§ãããã®ã¯æ¥µåãã¡ãã§å¯¾å¿ããã¦ããã®ãè¯ãã¨æãã¾ãã
@ExampleObject
ã§ãããexternalValue
ã«ã¯ã©ã¹ãã¹ãæå®ãã¦ããããã«ããJSONãã¡ã¤ã«ãèªã¿è¾¼ãã§ã¯ããã¾ããã§ãã*4ã
ãªã®ã§ã³ãã³ãã¨ãã¿ã§æ¸ãè¾¼ããã¨ã«ãªãã¾ã*5ã
@GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼æ å ±ãæ¤ç´¢ãã¾ã") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = UserResponse.UserResponseBody.class), examples = { @ExampleObject( name = "default", value = "{\n" + " \"body\": {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:example\",\n" + " \"id\": \"100\"\n" + " },\n" + " \"ok\": true\n" + "}") }) }, responseCode = "200") @Parameters({@Parameter(name = "id", description = "ã¦ã¼ã¶ã¼ID")}) public Response getUserById(@PathParam("id") String id) {
ã¬ã¹ãã³ã¹ã®å®ç¾©ãã¡ããã¨åºã¦ãã¾ããã
ï¼ç¹ã解決ãåºæ¥ãªãã£ããã¨ãããã¾ãã
ãªã¯ã¨ã¹ãã¨ã¬ã¹ãã³ã¹ãç¶æ¿ã§å®è£
ããã®ã§ããããããããã®å½±é¿ã§Enumé¨åã®è¦ç´ ãéè¤ãã¦ç»é²ããã¦ãã¾ãã¾ããã
ã¾ãããã¬ã¹ãã³ã¹ã¯åãæãªã®ã§å®å®³ã¯å°ãªãã¨ãããã¨ã§ãããã¯ç®ãã¤ã¶ããã¨ã«ãã¾ããã
ã¯ã¨ãªã使ã£ãåãåãã
ã¯ã¨ãªã使ã£ãå ´åã¯è¤æ°ã®çµæãè¿å´ãããã¨ãããã®ã§é
åãæ»ãå¤ã®åã«ãªãã¾ãã
å®ç¾©ã®ã³ã¼ãå®è£
ã¯ãããªæãã§ãã
static class UserResponseListBody extends BaseResponseBody { @SuppressFBWarnings("UUF_UNUSED_FIELD") private List<UserResponse> body; }
æ¬æ¥ãResponseListBodyã®ããããã£ãè¨è¿°ããªãã¦è¯ãã®ã§ãããOpenAPIã§å®ç¾©ããåæ å ±ã¨ãã¦ã¯ãããããã£ãä¸æ¸ããããããªã³ã¼ããæ¸ããã¨ã«ãªãã¾ãã
æè¦çã«ã¯ä»¥ä¸ãªã®ã§ãããããã ã¨Genericã List
ã®å
¥ãåã«ãªã£ã¦ãã¦åºåãããOpenAPIã®å®ç¾©ã«ã¯ã©ã¹åã®ã¹ãã¼ããè¨å®ããã¾ãã*6ã
static class UserResponseListNgBody extends ResponseListBody<UserResponse> {}
ãããã«ãã¦ãããã®ã¤ã³ãã¼ã¯ã©ã¹ã¯ãOpenAPIã®ã¹ãã¼ããåºåããããã®ã¯ã©ã¹ããªã®ã§ããããã£ããã§ããã ãããã®æ°æã¡ã§å²ãåã£ãæ¹ãè¯ãã¨æãã¾ã*7ã
ä¸è¨ã«å ãã¦ãè¤æ°ã®@ExampleObject
ã使ãå®è£
ä¾ã示ãã¾ãã
ä¾ãã°ãexampleã®ä¾ç¤ºã¨ãã¦ï¼ãã¿ã¼ã³ã示ããããã¨ãããããããã¾ããã
name
ããã¼ã¨ãã¦å®ç¾©ãããã¿ã¼ã³ã®è¡¨ç¤ºãåãæ¿ãããã¨ãã§ãã¾ãã
Enumã使ã£ãé¸æè¢ã®å®ç¾©ãã§ãã¾ãã
ãããããã¨ã§å®æ°åãã¤ãã£ãå®ç¾©ãã§ããã®ã§å©ç¨å´ã宣è¨çãªå®è£
ãå¯è½ã«ãªãã¾ã*8ã
@GET @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "ã¦ã¼ã¶ã¼æ å ±ãæ¤ç´¢ãã¾ã", operationId = "getUsersByQuery", description = "ã¯ã¨ãªã¼ã§æå®ããæ¡ä»¶ãçµãè¾¼ã¿æ¡ä»¶ã¨ãã¦ä½¿ç¨ãã¾ãã<br>" + "æ¡ä»¶ãæå®ããªãå ´åã¯å ¨ã¬ã³ã¼ããåå¾å¯¾è±¡ã¨ãªãã¾ã") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = UserResponse.UserResponseListBody.class), examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"body\": [\n" + " {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:example\",\n" + " \"id\": \"100\"\n" + " }\n" + " ],\n" + " \"ok\": true\n" + "}"), @ExampleObject( name = "return 2 record", value = "" + "{\n" + " \"body\": [\n" + " {\n" + " \"gender\": \"MALE\",\n" + " \"name\": \"Name:user name1\",\n" + " \"id\": \"1\"\n" + " },\n" + " {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:user name2\",\n" + " \"id\": \"2\"\n" + " }\n" + " ],\n" + " \"ok\": true\n" + "}") }) }, responseCode = "200") @Parameters({ @Parameter( name = "gender", description = "æ§å¥", schema = @Schema( enumeration = {"MALE", "FEMALE", "OTHER"}, implementation = String.class)), @Parameter(name = "name", description = "ã¦ã¼ã¶ã¼å", example = "user name") }) public Response getUsersByQuery( @QueryParam("gender") Gender gender, @QueryParam("name") String name) {
ã¡ãã£ã¨åããã«ããã§ãããé
åã«ãªã£ã¦ãã¾ããï¼[
]
ãããã¾ããï¼ã
ã¯ã¨ãªãã¤ãã£ãåãåããï¼@BeanParamï¼
ã¯ã¨ãªã§ï¼ã¤ï¼ã¤ã®å¤æ°ãã¡ã½ããã®å¼æ°ã¨ãã¦å®ç¾©ãããããã@BeanParam
ã§ï¼ã¤ã«ã¾ã¨ãã¦ä½¿ããããããããã®ã§ãã
ã§ããã° BeanParam
å
ã®ã¯ã©ã¹ã§ãã©ã¡ã¼ã¿ã®è¨å®ãã§ããã¨OpenAPIã®è¨è¿°ã¨ãã¦ãå
±éåã§ããã®ã§è¯ãã£ãã®ã§ãããæ®å¿µãªãã @Parameters
ãã¡ã½ããã«ããé©ç¨ã§ããªãã®ã§åé·ã§ã¯ããã¾ãããã¡ã½ããåä½ã§åããã¨ãè¨è¿°ããå¿
è¦ãããã¾ãã
åºæ¬ã¯ãã¿ã§ã¢ããã¼ã·ã§ã³ã§å®ç¾©ããã®ã¨éãã¯ããã¾ããã
@BeanParam
ã®è¦ç´ ããã¹ã¦è¨è¿°ããã ãã§ãã
ãã¤ã³ãã¯ãin = ParameterIn.QUERYãã¨ããããã«ã@BeanParam
ã®ã¢ããã¼ã·ã§ã³ã§æå®ãããã£ã¼ã«ãã«ä»ä¸ããã¢ããã¼ã·ã§ã³ï¼ä¾ãã° @QueryParam
ï¼ã¨åã£ãå®ç¾©ã追è¨ããã¨ããã§ã*9ã
@GET @Path("beamparam") @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "ã¦ã¼ã¶ã¼æ å ±ãæ¤ç´¢ãã¾ãï¼BeanParamã使ç¨ï¼", description = "ã¯ã¨ãªã¼ã§æå®ããæ¡ä»¶ãçµãè¾¼ã¿æ¡ä»¶ã¨ãã¦ä½¿ç¨ãã¾ãã<br>" + "æ¡ä»¶ãæå®ããªãå ´åã¯å ¨ã¬ã³ã¼ããåå¾å¯¾è±¡ã¨ãªãã¾ãã<br>" + "ï¼BeanParamã«ããã¯ã¨ãªã¼æå®ãããã¨OpenAPIã§ã¯æå®ãã§ãã¾ããã<br>") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = UserResponse.UserResponseListBody.class), examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"body\": [\n" + " {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:example\",\n" + " \"id\": \"100\"\n" + " }\n" + " ],\n" + " \"ok\": true\n" + "}") }) }, responseCode = "200") @Parameters({ @Parameter( name = "gender", in = ParameterIn.QUERY, description = "æ§å¥", schema = @Schema(ref = "#/components/schemas/Gender")), @Parameter( name = "name", in = ParameterIn.QUERY, description = "ã¦ã¼ã¶ã¼å", schema = @Schema(example = "User Name", implementation = String.class)) }) public Response getUsersByBeanParam(@BeanParam UserQueryParam userQueryParam) {
@BeanParam
ã¯JAX-RSã®å®è£
ã ãã§Open-APIã®ã¢ããã¼ã·ã§ã³ã¯ããã¾ããã
@lombok.Data public class UserQueryParam { @QueryParam("gender") private Gender gender; @QueryParam("name") private String name; }
POST
ãã¤ã³ãã¯ãªã¯ã¨ã¹ãããã£ã® @ExampleObject
ãå®ç¾©ããã¨ããã§ãã
ããã OpenAPI-UIã®ãªã¯ã¨ã¹ãããã£ã®éå½¢ã«ãªãã¾ãã
ä¾ãã°ãè¤æ°ãã¿ã¼ã³ãæºåãããæã¯è¤æ°è¨è¿°ãããã¨è¯ãã§ãããã
@POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼æ å ±ãç»é²ãã¾ã") @APIResponse( content = @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = UserResourceId.UserResponseIdBody.class), examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"body\": {\n" + " \"id\": \"57d1a3b9-bb09-42f4-9913-941de0a7d4cb\"\n" + " },\n" + " \"ok\": true\n" + "}") }), responseCode = "201") @RequestBody( content = @Content( mediaType = MediaType.APPLICATION_JSON, examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"gender\": \"MALE\",\n" + " \"name\": \"Name:name-1\"\n" + "}") })) public Response postUser(UserRequest userRequest) {
ãªã¯ã¨ã¹ãããã£ã®ã¯ã©ã¹ã« OpenAPIã®å®ç¾©ãè¨è¿°ãã¦ãã¾ãã
ãã¡ãã®Enumï¼ï¼ã¤ã®è¦ç´ ï¼ã¯ãæ¡å¼µãã¦ä½æããã¬ã¹ãã³ã¹ã¯ã©ã¹ã®çµæã¨éã£ã¦ãå®ç¾©éããï¼ã¤ã§ãã
ã¨ãããããã¯ã©ã¤ã¢ã³ãã¨ãã¦ã¯ä»æ§ã¨ãã¦å¦¥å½ãªãã®ãæ示ããã¦ããã¨ãããã¨ã§å第ç¹ããªï¼ã¨ã
@lombok.Data @lombok.NoArgsConstructor @Schema public class UserRequest { @Schema( title = "æ§å¥", example = "OTHER", enumeration = {"MALE", "FEMALE", "OTHER"}, required = true) private String gender; @Schema(title = "ã¦ã¼ã¶ã¼å", example = "User Name", required = true) private String name; User toModel() { return this.toModel(null); } User toModel(String userId) { var model = User.builder() .userId(Objects.isNull(userId) ? null : UserId.of(userId)) .gender(Gender.valueOf(this.gender)) .name(Text.of(name)) .build(); return model; } }
PUT
ç¹ã«ãããã¨ã¯ç¡ãâ¦
@PUT @Path("{id}") @Consumes(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼æ å ±ãæ´æ°ãã¾ã") @APIResponse(responseCode = "204") @Parameters({ @Parameter( name = "id", description = "ã¦ã¼ã¶ã¼ID", example = "57d1a3b9-bb09-42f4-9913-941de0a7d4cb") }) @RequestBody( content = @Content( mediaType = MediaType.APPLICATION_JSON, examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"gender\": \"MALE\",\n" + " \"name\": \"Name:name-1\"\n" + "}") })) public void putUser(@PathParam("id") String id, UserRequest userRequest) {
DELETE
ãã¡ããç¹çãããã¨ã¯ãªãâ¦
@DELETE @Path("{id}") @Consumes(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼æ å ±ãåé¤ãã¾ã") @APIResponse(responseCode = "204") @Parameters({ @Parameter( name = "id", description = "ã¦ã¼ã¶ã¼ID", example = "57d1a3b9-bb09-42f4-9913-941de0a7d4cb") }) public void deleteUser(@PathParam("id") String id) {
ãã¡ã¤ã«ã¢ãããã¼ã
WebAPIã¨ãã¦ãã¡ã¤ã«ãã¢ãããã¼ããããã¨ããããã£ã¦ããããã¨ããã§ãã
åä¸ãã¡ã¤ã«
ä¾ç¤ºã®ããã«ã¢ããã¼ã·ã§ã³ã§å®ç¾©ãã§ãã¾ãããã¢ãããã¼ãããå ´åã¯å¸¸ã«åãè¨è¿°ãããã®ã§ã³ã¼ãã§ã¹ãã¼ãå®ç¾©ãä½æãã¦å©ç¨ããã¨ããããæ¹ãã§ãã¾ãã
@POST @Path("{id}/file") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼ã«é¢é£ãããã¡ã¤ã«ãã¢ãããã¼ããã¾ã") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = BaseResponseBody.class), examples = @ExampleObject(name = "default", value = "{\"ok\": true}")) }, responseCode = "200") @Parameters(@Parameter(name = "id", description = "ã¦ã¼ã¶ã¼ID")) @RequestBody( description = "ã¢ãããã¼ããã¡ã¤ã«ãé¸æãã¦ãã ãã", content = @Content( mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema( type = SchemaType.OBJECT, properties = { @SchemaProperty(name = "file", type = SchemaType.STRING, format = "binary"), }))) public Response postUploadUserFile(@PathParam("id") String id, EntityPart file) {
ã¹ãã¼ãã®å®ç¾©ç
@POST @Path("{id}/file") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼ã«é¢é£ãããã¡ã¤ã«ãã¢ãããã¼ããã¾ã") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = BaseResponseBody.class), examples = @ExampleObject(name = "default", value = "{\"ok\": true}")) }, responseCode = "200") @Parameters(@Parameter(name = "id", description = "ã¦ã¼ã¶ã¼ID")) @RequestBody( name = "file", description = "ã¢ãããã¼ããã¡ã¤ã«ãé¸æãã¦ãã ãã", content = @Content( mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(ref = "#/components/schemas/UploadFile"))) public Response postCustomUploadUserFile(@PathParam("id") String id, EntityPart file) {
ã¹ãã¼ããå®ç¾©ãã¦èªã¿è¾¼ã
å®ç¾©ã®èªã¿è¾¼ã¿ã¯ OASModelReader
ã®å®è£
ã§è¡ãã¾ãã
ã¾ãã¯ã¹ãã¼ããçæããã³ã¼ãã
ä»ã®ããã¸ã§ã¯ãã§ãåããã¨ãããã®ã§Utilã«ãã¦ãã¾ãã
/** * è¤æ°ãã¡ã¤ã«ã®ã¢ãããã¼ããå®ç¾©ããã¹ãã¼ããä½æãã¾ã. * * @param propertyName ã¹ãã¼ãã®ããããã£å * @return è¤æ°ãã¡ã¤ã«ã®ã¢ãããã¼ãããã¹ãã¼ã */ public static Schema createUploadFileSchema(String propertyName) { return OASFactory.createSchema() .description("ã¢ãããã¼ããæå®ããããã®ã¹ãã¼ãã§ã.") .type(Schema.SchemaType.OBJECT) .properties( Map.of( propertyName, OASFactory.createSchema().type(Schema.SchemaType.STRING).format("binary"))); }
ããã OASModelReader.buildModel()
ã®ä¸ã§å®ç¾©ãã¾ãã
var components = OASFactory.createComponents() .addSecurityScheme("access_token", securityScheme) .addSchema("Gender", OpenApiSchemaUtil.createEnumSchema(Gender.class)) .addSchema("Genders", OpenApiSchemaUtil.createEnumListSchema(Gender.class)) .addSchema("UploadFile", OpenApiSchemaUtil.createUploadFileSchema()) .addSchema("UploadFiles", OpenApiSchemaUtil.createUploadFileListSchema());
ãããªæãã§ç¬èªã®ã¹ãã¼ãã¯ï¼ã¤ï¼ã¤è¿½å ãã¾ã*10ã
OpenAPI-UIã¨ãã¦ã¯ä»¥ä¸ã®ããã«ãã¡ã¤ã«ãæå®ã§ãã¾ãã
è¤æ°ãã¡ã¤ã«
ã¢ããã¼ã·ã§ã³ã§ãªãã¸ã§ã¯ãã®ãªã¹ãæ§é ãå®ç¾©ãããã¨ã¯åºæ¥ã¾ããã§ããã
ããã¯ã³ã¼ãã§ã®çæä¸æã§ãã
@POST @Path("{id}/files") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "ã¦ã¼ã¶ã¼ã«é¢é£ãããã¡ã¤ã«ãè¤æ°ã¢ãããã¼ããã¾ã") @Parameters(@Parameter(name = "id", description = "ã¦ã¼ã¶ã¼ID")) @RequestBody( name = "files", description = "ã¢ãããã¼ããã¡ã¤ã«ãé¸æãã¦ãã ãã", content = @Content( mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(ref = "#/components/schemas/UploadFiles"))) @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = BaseResponseBody.class), examples = @ExampleObject(name = "default", value = "{\"ok\": true}")) }, responseCode = "200") public Response postCustomUploadUserFiles(@PathParam("id") String id, List<EntityPart> files) {
ã¡ãªã¿ã«ããã調ã¹ã§ã¯ã¤ã¤æãã®ãã®ãè¦ã¤ãããªãã£ãã®ã§ãOpenAPIã®å®ç¾©ãè¦ã¤ã¤ãããããæãã«ãªã£ããããããããªãããªï¼ãã¨å½ã¦æ¨éè¾¼ã¿ã§è©¦ãã¦ãã£ã¦è¦ã¤ããæãã§ãã
public static Schema createUploadFileListSchema(String propertyName) { return OASFactory.createSchema() .description("ã¢ãããã¼ããè¤æ°æå®ããããã®ã¹ãã¼ãã§ã.") .type(Schema.SchemaType.OBJECT) .properties( Map.of( propertyName, OASFactory.createSchema() .type(Schema.SchemaType.ARRAY) .items( OASFactory.createSchema() .type(Schema.SchemaType.STRING) .format("binary")))); }
OpenAPI-UIã§ãè¤æ°ãã¡ã¤ã«ãæå®ã§ããããã«ãªã£ã¦ãã¾ããã
Enumã®ãªã¹ããã¯ã¨ãªãã©ã¡ã¼ã¿
Enumã¨ããªãã¸ã§ã¯ãããªã¹ãã¨ã¨ãã¦ã¯ã¨ãªãã©ã¡ã¼ã¿ã«å®ç¾©ããå ´åã¯ãã¢ããã¼ã·ã§ã³ã§ã¯å®ç¾©ã§ãã¾ããã§ããã
ãªã®ã§ãã³ã¼ãã§å¯¾å¿ï¼OASModelReader
ã§è¨å®ã§å¯¾å¿ãã¾ããã
Enumã® name
ããã®ã¾ã¾ä½¿ç¨ããå ´åã§ããã°ããã§è¯ãã¨æãã¾ãã
ããã³ã¼ãå¤ãå¤æãããããªã±ã¼ã¹ãããã°ã¤ã³ã¿ã¼ãã§ã¼ã¹ãEnumã«ã¤ãã¦ï¼ãã¨ãã° getCd
ã¿ãããªï¼èªã¿è¾¼ãããã«ããã°å®ç¾å¯è½ã§ãã
public static Schema createEnumListSchema(Class<? extends Enum<?>> enumClass) { var enums = enumClass.getEnumConstants(); return OASFactory.createSchema() .description(enumClass.getSimpleName() + "ãè¤æ°æå®ããããã®ã¹ãã¼ãã§ã.") .example(enums[0].name()) .type(Schema.SchemaType.ARRAY) .items( OASFactory.createSchema() .type(Schema.SchemaType.STRING) .enumeration(Stream.of(enums).map(Enum::name).collect(Collectors.toList()))); }
ã¡ãªã¿ã«ãªã¹ãã§ã¯ãªãEnumãã¤ãã§ã«ã¤ããã¾ããã
ãããããã° enumeration
ãåæããªãã¦è¯ããªãã¾ã*11ã
public static Schema createEnumSchema(Class<? extends Enum<?>> enumClass) { var enums = enumClass.getEnumConstants(); return OASFactory.createSchema() .description(enumClass.getSimpleName() + "ã®ã¹ãã¼ãã§ã.") .example(enums[0].name()) .type(Schema.SchemaType.STRING) .enumeration(Stream.of(enums).map(Enum::name).collect(Collectors.toList())); }
ãããã£ã¦ã¤ãã£ãã¹ãã¼ãå®ç¾©ã ref
ã§æå®ãã¾ãã
@GET @Path("enumlist") @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "ã¦ã¼ã¶ã¼æ å ±ãæ¤ç´¢ãã¾ã", description = "ã¯ã¨ãªã¼ã§æå®ããæ¡ä»¶ãçµãè¾¼ã¿æ¡ä»¶ã¨ãã¦ä½¿ç¨ãã¾ãã<br>" + "æ¡ä»¶ãæå®ããªãå ´åã¯å ¨ã¬ã³ã¼ããåå¾å¯¾è±¡ã¨ãªãã¾ã") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = UserResponse.UserResponseListBody.class), examples = { @ExampleObject( name = "default", value = "" + "{\n" + " \"body\": [\n" + " {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:example\",\n" + " \"id\": \"100\"\n" + " }\n" + " ],\n" + " \"ok\": true\n" + "}"), @ExampleObject( name = "return 2 record", value = "" + "{\n" + " \"body\": [\n" + " {\n" + " \"gender\": \"MALE\",\n" + " \"name\": \"Name:user name1\",\n" + " \"id\": \"1\"\n" + " },\n" + " {\n" + " \"gender\": \"OTHER\",\n" + " \"name\": \"Name:user name2\",\n" + " \"id\": \"2\"\n" + " }\n" + " ],\n" + " \"ok\": true\n" + "}") }) }, responseCode = "200") @Parameters({ @Parameter( name = "genders", description = "æ§å¥ï¼è¤æ°æå®ï¼", schema = @Schema(ref = "#/components/schemas/Genders")), @Parameter( name = "gender", description = "æ§å¥", schema = @Schema(ref = "#/components/schemas/Gender")), @Parameter( name = "name", description = "ã¦ã¼ã¶ã¼å", example = "user name", schema = @Schema(implementation = String.class)) }) public Response getUsersByQueryWithListEnum(
ãæ§å¥ï¼è¤æ°æå®ï¼ãã®é¸æè¢ã ctrlãæ¼ããªããé¸æãããè¤æ°ã®Enumå±æ§å¤ãæ¤ç´¢æ¡ä»¶ã¨ãã¦æå®ã§ãã¾ãã
Exceptionï¼2xx系以å¤ã®ã¹ãã¼ã¿ã¹ï¼
ããæ¹ã¯è²ã ã¨ããã¨æãã¾ãã
- ã¡ã½ããã«ï¼ã¤ï¼ã¤è¨è¿°ãã
OASModelReader
ã使ã£ã¦å ¨ã¡ã½ããã«ã¤ãã- ãã®èª¬æç¨ã®URLãä½ãï¼ä»åã¯ã³ã¬ï¼
ä¸è¬çã«ã¯ä¸ï¼ã¤ã®ããããã ã¨æãã®ã§ãã
- 4xxã5xx ã¯å¤ãã®å ´åãã»ã¼åãäºæ¸ãã ã
- ã¡ã½ããã®ã¬ã¹ãã³ã¹ã¨ãã¦æ³å®ã§ããHTTPã¹ãã¼ã¿ã¹ã ããæ¸ãããæ¹ããããã©ãããããã¨çµå± 5xxãªã©ã®ã·ã¹ãã åºç¤ã¨ãã¦å®ç¾©ãããã®ã®æ±ããã©ãããï¼ã¨ããã®ã¯æ®ã£ã¦ãã¾ã
- æ³å®ã§ããï¼è¨è¨ããï¼ä»¥å¤ã®ãã¿ã¼ã³ã®æç¡ã¯ãµã¼ãã¹ããæ·±ãæ次第ã§å¤ãã£ã¦ãããå ¨é¨ãControlleråä½ã§ææ¡ã§ãããã®ã§ãå®éã®ã¨ãããªãã®ã§ã¯ï¼
ã¨èãã¦ããä¸ã§ã次ã«ãå©ç¨å´ã¨ãã¦ä½ã欲ããï¼ãã¨èããã¨ãã«
- 4xxã5xxã¯å ±éãã¦ããã³ãã¨ãã¦ããã³ããªã³ã°ãããã¨ãå¤ã
- å ±éé¨åã§å¯¾å¿ãããã¨ãã«æ¥ç¶ãã¹ãããããããã®ãããã¨å¬ãã
ã¨ããããã«èãè³ããExceptionController
ãä½ãã¨ããè¨è¨ã«è½ã¡çãã¾ããã
å ¨éã¯é·ãã®ã§ä¸é¨æç²ã§ãã
@Path("/openapi-http-ng-status") @Tag(ref = "ExceptionController") @EntryPoint @SuppressWarnings("checkstyle:MissingJavadocMethod") public class ExceptionController { @SuppressWarnings("resource") @GET @Path("{httpStatus}") @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Httpã®NGã¹ãã¼ã¿ã¹ã®ã¬ã¹ãã³ã¹ä»æ§", operationId = "getHttpNgStatus", description = "" + "å¤ãã®ã±ã¼ã¹ã§ã¯2xx以å¤ã®ã¹ãã¼ã¿ã¹ã¯ExceptionHandlerãªã©ã§ä¸æ¬ãã¦æä½ãè¡ãã¾ã.<br>\n" + "åAPIæ¯ã«4xxã®ã¹ãã¼ã¿ã¹ä»æ§ãè¨è¼ããããå ±éãã¦åºåãããããªå®è£ ã追å ãããã¨ãã§ãã¾ãã<br>\n" + "åé·ãªè¨è¼ãæ¸ããããæ¬URLã«4xxããã³5xxã®APIä»æ§ã¯æ¬URLã¸éç´ãã¾ã.\n" + "ã¯ã©ã¤ã¢ã³ãã«ã¦4xx,5xxã®Httpã¹ãã¼ã¿ã¹æ¯ã®å¶å¾¡ç¢ºèªã§ã®å©ç¨ãæ³å®ãã¦ãã¾ã.") @APIResponse( content = { @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ErrorResponse.ErrorResponseBody.class), examples = { @ExampleObject( name = "default", value = "{\n" + " \"ok\": false,\n" + " \"body\": {\n" + " \"errors\": [\n" + " {\n" + " \"message\": \"æ§æãç¡å¹ã§ã\",\n" + " \"messageCode\": \"HTTP_STATUS_BAD_REQUEST\"\n" + " }\n" + " ]\n" + " }\n" + "}") }) }, responseCode = "400")
Code
experimentation/ee10-01-openapi at openapi · vermeerlab/experimentation · GitHub
ã«ã¼ãã®ããã¸ã§ã¯ãã§
./mvnw package
ããã¦ãå ¨ããã¸ã§ã¯ãããã«ããã¦ãã
ee10-01-openapi
ããã¸ã§ã¯ãã§
./mvnw cargo:run -Ppayara
ããã¦ãã
http://localhost:8081/ee10-01-openapi/api/openapi-ui/index.html
åè
ãã¡ãã«OpenAPIã®ã¡ã¢ã¯åæ
ãããã«
Quarkusç¨ã®OpenAPI-UIã©ã¤ãã©ãªã ã£ãããSpringã ã£ããspringdoc-openapi ã ã£ããã ã¨è²ã
ã¨ããã£ã¦ã¿ã¦æã£ããã¨ããã©ã¤ãã©ãªã解æ¶ãã¦ããã¾ãã
æ¨æºä»æ§ã®ç¯çã ã¨ãã®è¾ºãã¯èªåã§ä½ãè¾¼ã¾ãªãã¨ãããªãã®ã§ããã£ã¡ã ã¨ã§ããã¿ãããªãã ãã©ãªããã¨ã¢ã¤ã¢ã¤ãããã¨ãå¤ãã£ãã§ãã
ã¨ã¯ãããå®ç¾æ¹æ³ãåãã£ã¦ããã¨é¢åãªãã¨ã¯é¢åã§ããJavaDocãæ¸ãã¦ãã代ããã ã¨å²ãåã£ã¦ããã¯å°ãè©ã®åãæããæ°ããã¾ãã
ã¨ã«ããã³ãã³ã試ãã¦ã¿ã¦ãã£ã¦ã¿ãããã¨ã¯ä¸å¿å®ç¾ããã¨ããã¾ã§ãã©ãçããã®ã¯è¯ãã£ãã§ãã
ããã«ãã¦ãEEç³»ã§OpenAPIã®è¨äºãæ¬å½ã«å°ãªããªãã¨æãã¾ããã
ãã¡ãã£ã¨ãã£ã¦ã¿ããã¯ããã®ã§ãããå®ç¨ã¬ãã«ã®ãã®ãå°ãªãã¨ãããâ¦
å人çã«ã¯WebAPIã®ãã¹ãç¨IFã¨ãã¦OpenAPI-UIã¯ä½¿ããããã®ã§ãããã¡ãã£ã¨æ®åãã¦ãã¦ãè¯ãããã«æã£ã¦ããã®ã§ããããã¹ãç³»ã¯è«è² éçºã ã¨ã¨ã¯ã»ã«ã¸ã®ã³ããã§ç´åç©ãä½ãç³»ã®WFéçºã¨ãã¦ã¯ä½è¨ãªä½æ¥ï¼çµæãã£ããã¨ã®ãã人ãå°ãªããã¿ãããªæããªãã§ãããããï¼*12
*1:ãããè¦ã¤ããããã®ããä»åã®ã¢ã¬ã³ã¬ãã£ã¦ã¿ã¦å人çã«ã¯ä¸çªã®åç©«
*2:springdoc-openapi ã¯ãã£ã¦ããã
*3:ãã¾ããªãï¼ï¼ï¼ã¿ãããªæãã§ä½¿ã£ã¦ãã¾ã
*4:å°ãªãã¨ãPayaraã§ã¯ããã®ãããã¯Quarkusã ã¨åºæ¥ããããã¿ãããªã®ã§å®è£ ä¾åãªããã§ã
*5:ãã®è¾ºãã¯ã¡ãã£ã¨èªåã§é å¼µã£ã¦ãè¯ããããããªãã¨æãã¾ãããã¾ã㯠ãªã¬ãªã¬FWçãªãã¨ãããªããã¿ãªããæ¹ã§åºæ¥ããã¨ãæ´çãã¾ã
*6:ãããã¾ããè²ã ãã£ã¦ã¿ã¦è¯ãã£ããã®ã®ï¼ã¤
*7:ããã«ã©ã¤ãã©ãªã®ã¢ãããã¼ãã§ä¸è¦ã«ãªããããããªããããªããªããããããªãããã¹ããã©ã¯ãã£ã¹ã¨ãããããããªãã¨ãè¦ã¤ããTIPSãã§ã
*8:ããã§ã¯ãããã¦ãã¿ã§å®ç¾©ããæ¸ãæ¹ã®ä¾ã¨ãã¦ã¹ãã¼ããä½æãã¦è¨å®ããã¨ããããæ¹ããã¦ãã¾ãã
*9:ã¯ãããinãå±æ§ã¯ä½ã«ä½¿ãã®ãåãã£ã¦ããªãã£ãã®ã§ãããã¹ãæ¸ãã§çæãããã®ã¨è¦æ¯ã¹ã¦ãinãå±æ§ã足ãã¦ããªããã¨ãåãã£ã¦å¯¾å¿æ¹æ³ãåããã¾ããããããè¦ã¤ãã£ã¦æ¬å½ã«è¯ãã£ã
*10:éã«ããã¨è¿½å ããªãã¨ãããªãã®ããã¡ãã£ã¨æ®å¿µã¨ãè¨ãã¾ã
*11:#/components/schemas/ ãæååã§æ¸ããªãã¨ãããªãã¨ããã®ã¯æ®ã£ã¦ãã¾ãã¾ãããã¾ãããã§ãå ±éåã§ããã ããã·ã¨ãããã¨ã§
*12:ã¦ããããã¹ããä½ããªãã®ã¨ä¼¼ã¦ããçç±ãç´åç©ãä½ãå·¥æ°ã¨ãã¦ç©ã¿ã«ãã