Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate OpenAPI #15

Open
1 task
thekid opened this issue Apr 1, 2022 · 0 comments
Open
1 task

Integrate OpenAPI #15

thekid opened this issue Apr 1, 2022 · 0 comments
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@thekid
Copy link
Member

thekid commented Apr 1, 2022

Implementation

Using the unpkg CDN, we could simply serve the following from /api:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>SwaggerUI</title>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/swagger-ui.css" />
</head>
<body style="margin: 0">
  <div id="swagger-ui"></div>
  <script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" crossorigin></script>
  <script src="https://unpkg.com/[email protected]/swagger-ui-standalone-preset.js" crossorigin></script>
  <script>
    window.onload = () => {
      window.ui = SwaggerUIBundle({
        url: '/api/openapi.json',
        dom_id: '#swagger-ui',
        presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
        layout: 'StandaloneLayout',
      });
    };
  </script>
</body>
</html>

See also https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/installation.md#unpkg

We then need to decide how we want to create the openapi.json file:

Generate from API docs

Use YAML embedded in the api doc comments like https://github.com/Surnet/swagger-jsdoc:

/**
 * @openapi
 * /:
 *   get:
 *     description: Welcome to swagger-jsdoc!
 *     responses:
 *       200:
 *         description: Returns a mysterious string.
 */
app.get('/', (req, res) => {
  res.send('Hello World!');
});

Generate from annotations

Like this example from https://javascript.plainenglish.io/how-to-implement-and-use-swagger-in-nodejs-d0b95e765245:

@Operation(summary = "Sets a price for a chosen car", description = "Returns 202 if successful")
@ApiResponses(
  value = [
      ApiResponse(responseCode = "202", description = "Successful Operation"),
      ApiResponse(responseCode = "404", description = "Such a car does not exist"),
  ]
)
@PostMapping("/price/{carId}", consumes = ["application/json"])
fun setPrice(
  @PathVariable carId: Int,
  @RequestBody @OASRequestBody(
    description = "New price for the car",
    content = [Content(
      mediaType = "application/json",
      schema = Schema(type = "number", format = "float", minimum = "0.0", example = "23000.34"),
    )]
  ) price: BigDecimal
): ResponseEntity<Unit> {
    carService.setPrice(carId, price)
    return ResponseEntity.accepted().build()
}

(Similar to https://zircote.github.io/swagger-php/)

Mixed approach

We can use some of the annotations here:

use web\rest\{Get, Post, Resource, Response};

#[Resource('/users')]
class Users {

  /**
   * Returns all users.
   *
   * - 200: Successful operation
   */
  #[Get('/')]
  public function listUsers($max= 10) {
    // $max comes from request parameter "max", defaulting to 10
    // ...
  }

  /**
   * Returns a given user.
   *
   * - 200: Successful operation
   * - 404: The user cannot be found
   */
  #[Get('/{id}')]
  public function findUser($id) {
    // $id is extracted from URL segment
    // ...
  }

  /**
   * Creates a user.
   *
   * - 201: Successful operation
   * - 400: Validation failed
   */
  #[Post('/')]
  public function createUser($user) {
    // $user is deserialized from the request body according to its content type
    // ...
    return Response::created('/users/{id}', $id)->entity($created);
  }
}

TODO: How do we denote request and response body schemas?

  • 200+UserList: Successful operation and then have UserList defined in the class' api doc?

(Similar to https://vyuldashev.github.io/laravel-openapi/)

@thekid thekid added help wanted Extra attention is needed good first issue Good for newcomers labels Apr 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant