title: How to use annotations to create OpenAPI (Swagger) documentation on Grails 4
body: <p>We are creating API documentation for an existing Grails 4 App. We are having difficulties in understanding how to use Swagger annotations.</p>
  
  <p>Let's assume the following Controller:</p>
  
  <pre><code>class IntegratorController {
  
      def maintenanceService
  
      def saveMaintenance() {
          def message = 'success'
          def status = '200'
  
          try {
              def maintenanceJson = request.JSON.maintenances
              def ret=maintenanceService.processMaintenanceJSON(maintenanceJson)
  
          } catch (Exception e) {
              log.error("Error to process restricions", e)
              message = 'error : ${e.getMessage()}'
              status = '500'
          }
  
          def result = ['message':message]
          render(status: status, contentType: "application/json", text: result as JSON)
      }
  
  }
  
  </code></pre>
  
  <p>This controller expects you to send a request JSON like this example:</p>
  
  <pre><code>{ "job":42,
    "maintenances": [
      {"idPort":42, "idMaintenance":42, "shipName":"myship01", "obs":"asap"},
      {"idPort":43, "idMaintenance":43, "shipName":"myship02", "obs":"asap"}]}
  </code></pre>
  
  <p>A basic annotation will be this:</p>
  
  <pre><code>@Controller("/")
  class IntegratorController {
  
      def maintenanceService
  
      @Post(uri="/saveMaintenance", produces = MediaType.APPLICATION_JSON)
      @Consumes(MediaType.APPLICATION_JSON)
      @Operation(summary = "Create one or more ship maintenance")
      @ApiResponse(responseCode = "500", description = "If internal service throws an Exception")
      def saveMaintenance() {
          def message = 'success'
          def status = '200'
  
          try {
              def maintenanceJson = request.JSON.maintenances
              def savedMaintenances=maintenanceService.processMaintenanceJSON(maintenanceJson)
  
          } catch (Exception e) {
              log.error("Error to process restricions", e)
              message = 'error : ${e.getMessage()}'
              status = '500'
          }
  
          def result = ['message':message]
          render(status: status, contentType: "application/json", text: result as JSON)
      }
  }
  </code></pre>
  
  <p>Where and how to annotate the request JSON sent in the post operation?</p>
  
  <p>Thank you!</p>