codeconsole opened a new pull request, #16275:
URL: https://github.com/apache/grails-core/pull/16275

   Adds an optional `grails-openapi` module so a Grails application can publish 
an OpenAPI description of its REST endpoints and browse it with Swagger UI.
   
   springdoc builds its document by scanning Spring MVC handler methods. Grails 
dispatches through `UrlMappingsHandlerMapping` rather than `@RequestMapping` 
handler methods, so springdoc on its own serves `/v3/api-docs` with no paths. 
This module supplies them through springdoc's `OpenApiCustomizer` SPI, and 
describes domain classes from the GORM mapping model.
   
   ## Usage
   
   ```groovy
   dependencies {
       implementation 'org.apache.grails:grails-openapi'
       implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui'
   }
   ```
   
   Grails serves static resources under `/static/**` and disables Spring Boot's 
resource handler, which Swagger UI needs:
   
   ```yaml
   spring:
       web:
           resources:
               add-mappings: true
   ```
   
   If the application has a catch-all mapping that resolves to a view or URI, 
exclude the springdoc paths so they reach Spring MVC:
   
   ```groovy
   class UrlMappings {
       static excludes = ['/swagger-ui/**', '/v3/api-docs/**']
   }
   ```
   
   Given:
   
   ```groovy
   class Book {
       String title
       String genre
   
       static constraints = {
           title blank: false, nullable: false, maxSize: 255
           genre nullable: true, inList: ['scifi', 'fantasy', 'history']
       }
   }
   
   class UrlMappings {
       static mappings = {
           "/books"(resources: 'book')
       }
   }
   ```
   
   `/v3/api-docs` describes the eight operations the `resources` mapping 
generates, and:
   
   ```json
   "Book": {
     "type": "object",
     "properties": {
       "id":      { "type": "integer", "format": "int64" },
       "title":   { "type": "string", "maxLength": 255 },
       "genre":   { "type": "string", "enum": ["scifi", "fantasy", "history"] },
       "version": { "type": "integer", "format": "int64" }
     },
     "required": ["title"]
   }
   ```
   
   `GET /books` responds with an array of `Book`, `GET /books/{id}` with one, 
and `POST`/`PUT`/`PATCH` accept a `BookRequest` body — the same schema without 
`id` and `version`, which a client does not supply. Operations addressed by an 
identifier also document a `404`.
   
   ## Constraint mapping
   
   | Constraint | OpenAPI |
   |---|---|
   | `nullable: false` | `required` |
   | `maxSize` / `size` | `maxLength`, `minLength` |
   | `min` / `max` / `range` | `minimum`, `maximum` |
   | `inList` | `enum` |
   | `matches` | `pattern` |
   | `email` / `url` | `format` |
   
   ## Limitations
   
   - Mappings whose controller is resolved per request, such as the default 
`"/$controller/$action?/$id?"`, are skipped: their controller and action are 
not known statically.
   - A mapping that accepts any HTTP method is documented as `GET`, because 
OpenAPI requires a concrete operation.
   - The mapping context is injected optionally, so an application without GORM 
still gets a document describing its paths, without schemas.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to