[RUBY] Créez un environnement de "développement d'API + vérification d'API à l'aide de Swagger UI" avec Docker

Vous pouvez utiliser Swagger pour documenter les spécifications de l'API REST. Dans Swagger, le fichier qui documente les spécifications de l'API REST est appelé Swagger Spec.

Swagger UI est un outil qui génère des pages statiques qui reflètent les informations Swagger Spec. L'interface utilisateur Swagger visualise non seulement les informations Swagger Spec, mais offre également la possibilité d'exécuter des API REST à partir de l'écran.

Cette fois, nous présenterons la procédure de création d'un environnement Docker qui vous permet d'effectuer une série de tâches telles que «Documenter l'API en cours de développement avec Swagger Spec → Vérification de la demande d'API à partir de l'écran Swagger UI qui reflète les informations Swagger Spec».

À propos de l'environnement Docker créé cette fois

Les spécifications sont les suivantes.

En utilisant nginx comme proxy inverse, vous pouvez combiner l'environnement de développement d'API avec l'interface utilisateur Swagger. La figure est la suivante.

スクリーンショット 2020-10-25 20.17.16.png

Les différentes versions utilisées cette fois sont les suivantes.

Créer un environnement de développement d'API dans Docker

Développement d'API en mode API Rails, en référence à la Procédure de construction de l'environnement Docker Rails 6 x MySQL 8 créée en mode API Créez un environnement.

Le Dockerfile et le docker-compose.yml sont les suivants.

Dockerfile


FROM ruby:2.7.1

#Directeur de travail/rails_api_Désigné comme swagger
WORKDIR /rails_api_swagger

#Copier Gemfile local sur Dokcer
COPY Gemfile* /rails_api_swagger/

# /rails_api_installation du bundle sur le répertoire swagger
RUN bundle install

docker-compose.yml


version: '3'
services:
  api: #Conteneur lancé par Ruby on Rails
    build: .
    ports:
      - '3000:3000' #Rendez-le accessible sur le port 3000 de localhost
    volumes:
      - .:/rails_api_swagger #Synchronisation des fichiers d'application
    depends_on:
      - db
    command: ["./wait-for-it.sh", "db:3306", "--", "./start.sh"]
  db: #Conteneur que MySQL démarre
    image: mysql:8.0.21
    volumes:
      - mysql_data:/var/lib/mysql #Persistance des données
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password #Définissez la méthode d'authentification sur 8 séries ou une version antérieure.
    environment:
      MYSQL_USER: 'webuser'
      MYSQL_PASSWORD: 'webpass'
      MYSQL_ROOT_PASSWORD: 'pass'
      MYSQL_DATABASE: 'rails_api_swagger_development'
volumes:
  mysql_data: #Enregistrement du volume de données

** Le mode API Rails exclut la possibilité de générer des pages statiques, vous ne pouvez donc pas intégrer l'interface utilisateur Swagger directement dans votre application Rails **, mais si vous utilisez cette méthode, vous pouvez également utiliser l'interface utilisateur Swagger en mode API. Je peux le faire.

Créez un exemple d'API.

#Démarrez le conteneur en arrière-plan
$ docker-compose up -d

#Créer des fonctions (modèles, vues, contrôleurs) pour faire fonctionner les événements à la fois
$ docker-compose exec api rails g scaffold event title:string

#Créer une table d'événements
$ docker-compose exec api rails db:migrate

#Créer un enregistrement des événements dans la console des rails
$ docker-compose exec api rails c
> event = Event.new(title: 'Exemple d'événement')
> event.save

C'est OK si vous accédez à localhost: 3000 / events et obtenez la réponse suivante.

Configurez un proxy inverse pour pouvoir accéder à l'API via nginx

Configurez le proxy inverse pour pouvoir accéder à votre application Rails via nginx.

default.conf


server {
  listen 80;
  server_name  localhost;

  # "/"Traitement lorsqu'il y a accès à
  location / {
    proxy_set_header Host localhost; #Définissez l'hôte de la source d'accès sur localhost
    proxy_pass http://api:3000; #Envoyez une demande au port 3000 du conteneur API
  }
}

Le fichier de configuration nginx est / etc / nginx / nginx.conf. Comme vous pouvez le voir dans la description ʻinclure /etc/nginx/conf.d / *. Conf; dans le fichier de configuration, il est appelé .conf sous / etc / nginx / conf.d` dans le fichier de configuration. Les paramètres d'extension sont également chargés.

En d'autres termes, le conteneur nginx peut être utilisé comme proxy inverse en plaçant le fichier de configuration créé cette fois sous / etc / nginx / conf.d.

Ajoutez le conteneur nginx à docker-compose.yml.

docker-compose.yml


services:
  api:
    (Abréviation)
  db:
    (Abréviation)
  nginx:
    image: nginx:1.19.3
    ports:
      - '80:80'
    command: [nginx-debug, '-g', 'daemon off;']
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - api
volumes:
  mysql_data:

[nginx-debug, '- g', 'daemon off;'] est la méthode de démarrage en mode débogage. [^ nginx-debugmode]

Image Docker de swagger-ui utilise également nginx, mais ʻinclude / etc / in nginx.conf Il n'y a pas de description de nginx / conf.d / *. Conf; `. Veuillez donc noter que cette approche ne fonctionnera pas si vous utilisez l'image Docker de ** swagger-ui **.

Après avoir démarré le conteneur, accédez à localhost: 80 / events et obtenez la réponse suivante.

Incorporer l'interface utilisateur Swagger dans nginx

Lorsque vous accédez à / swagger-ui, nous incorporerons l'interface utilisateur Swagger dans nginx afin que l'écran de l'interface utilisateur Swagger soit affiché.

L'écran de l'interface utilisateur Swagger est composé de swagger-ui / dist.

L'interface utilisateur Swagger est intégrée dans nginx en copiant les fichiers sous dist localement et en les liant en les montant dans le conteneur nginx.

Vous pouvez copier tous les fichiers sous dist, mais en utilisant unpkg, vous pouvez simplement copier ʻindex.html` sur l'écran de l'interface utilisateur de Swagger. Peut être créé. [^ swagger-ui-installation]

index.html


<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Swagger UI</title>
-   <link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
+   <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist[email protected]/swagger-ui.css" >
    <style>
      html
      {
        box-sizing: border-box;
        overflow: -moz-scrollbars-vertical;
        overflow-y: scroll;
      }

      *,
      *:before,
      *:after
      {
        box-sizing: inherit;
      }

      body
      {
        margin:0;
        background: #fafafa;
      }
    </style>
  </head>

  <body>
    <div id="swagger-ui"></div>

-   <script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
+   <script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js" charset="UTF-8"> </script>
-   <script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
+   <script src="https://unpkg.com/[email protected]/swagger-ui-standalone-preset.js" charset="UTF-8"> </script>

    <script>
    window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        url: "https://petstore.swagger.io/v2/swagger.json",
        dom_id: '#swagger-ui',
        deepLinking: true,
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIStandalonePreset
        ],
        plugins: [
          SwaggerUIBundle.plugins.DownloadUrl
        ],
        layout: "StandaloneLayout"
      })
      // End Swagger UI call region

      window.ui = ui
    }
  </script>
  </body>
</html>

Modifiez docker-compose.yml et placez le ʻindex.html créé sous / usr / share / nginx / html`, qui est le répertoire public par défaut de nginx.

docker-compose.yml


services:![Capture d'écran 2020-10-25 18.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/22cf7096-e237-7c2e-3aa5-0959d4776657.png)

  api:
    (Abréviation)
  db:
    (Abréviation)
  nginx:
    image: nginx:1.19.3
    ports:
      - '80:80'
    command: [nginx-debug, '-g', 'daemon off;']
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
+     - ./nginx/html/swagger-ui:/usr/share/nginx/html/swagger-ui
    depends_on:
      - api
volumes:
  mysql_data:

Ajoutez les paramètres nginx pour que ʻindex.html s'affiche lorsque vous accédez à / swagger-ui`.

default.conf


server {
  listen 80;
  server_name  localhost;

  location / {
    proxy_set_header Host localhost;
    proxy_pass http://api:3000;
  }

  # "swagger-ui"Traitement lorsqu'il y a accès à
  location /swagger-ui {
    alias /usr/share/nginx/html/swagger-ui;
  }
}

Après avoir démarré le conteneur, accédez à localhost: 80 / swagger-ui et c'est OK si l'écran suivant s'affiche.

スクリーンショット 2020-10-25 18.23.07.png

Assurez-vous que la spécification Swagger locale est reflétée sur l'interface utilisateur Swagger

Vous pouvez modifier la spécification Swagger référencée en modifiant ʻurl` dans l'interface utilisateur de Swagger.

Modifiez-le pour référencer la spécification Swagger locale.

index.html


- url: "https://petstore.swagger.io/v2/swagger.json",
+ url: "./api.yml",

Avec les modifications ci-dessus, le contenu de . / Nginx / html / swagger-ui / api.yml placé dans l'environnement local sera reflété dans l'interface utilisateur de Swagger.

Le répertoire . / Nginx / html / swagger-ui / est monté en liaison, donc si vous éditez la spécification Swagger localement et que vous la rechargez ensuite, les modifications seront reflétées dans l'interface utilisateur Swagger du conteneur. ** **

La spécification Swagger qui exécute le GET / events créé comme exemple est la suivante.

api.yml


openapi: 3.0.2
info:
  title:Exemple d'API
  version: 1.0.0
servers:
  - url: http://localhost:3000
tags:
  - name:un événement
paths:
  /events:
    get:
      tags:
        -un événement
      description:Obtenir la liste des événements
      responses:
        200:
          description:Succès
          content:
            application/json:
              schema:
                type: array
                description:Tableau d'événements
                items:
                  $ref: "#/components/schemas/Event"
components:
  schemas:
    Event:
      type: object
      properties:
        id:
          description: ID
          type: integer
          format: int64
          example: 1
        title:
          description:Titre
          type: string
          example:Exemple d'événement
        created_at:
          description:Date de création
          type: string
          format: date-time
          example: 2020-04-01 10:00
        updated_at:
          description:Date de mise à jour
          type: string
          format: date-time
          example: 2020-04-01 10:00

Après avoir démarré le conteneur, c'est OK si l'écran suivant s'affiche.

スクリーンショット 2020-10-25 18.24.54.png

Définir CORS

L'interface utilisateur de Swagger fonctionne sur localhost: 80 et l'API s'exécute sur localhost: 3000. Si vous envoyez une requête à l'API depuis l'interface utilisateur Swagger dans cet état, elle chevauche l'origine. Erreur se produit.

スクリーンショット 2020-10-25 18.37.42.png

Configurez CORS afin que les demandes d'API puissent être envoyées depuis l'interface utilisateur de Swagger. Cette fois, utilisez rack-cors pour définir CORS.

Gemfile


gem 'rack-cors'

config/initializers/cors.rb


Rails.application.config.middleware.insert_before 0, Rack::Cors do
  unless Rails.env.production?
    allow do
      origins(['localhost', /localhost:\d+\Z/])

      resource '*',
        headers: :any,
        methods: [:get, :post, :put, :patch, :delete, :options, :head]
    end
  end
end

Après avoir démarré le conteneur, c'est OK si la demande est retournée normalement.

スクリーンショット_2020-10-25_18_39_30.png

Référence: Swagger Spec qui effectue des opérations CRUD

La spécification Swagger pour les points de terminaison ci-dessus est:

api.yml


openapi: 3.0.2
info:
  title:Exemple d'API
  version: 1.0.0
servers:
  - url: http://localhost:3000
tags:
  - name:un événement
paths:
  /events:
    get:
      tags:
        -un événement
      description:Obtenir la liste des événements
      responses:
        200:
          description:Succès
          content:
            application/json:
              schema:
                type: array
                description:Tableau d'événements
                items:
                  $ref: "#/components/schemas/Event"
    post:
      tags:
        -un événement
      description:Inscription à l'événement
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  example:Exemple d'événement
      responses:
        201:
          description:Créer
  /events/{event_id}:
    get:
      tags:
        -un événement
      description:Détails de l'évènement
      parameters:
        - name: event_id
          in: path
          description:ID d'événement
          required: true
          schema:
            type: integer
            format: int64
            example: 1
      responses:
        200:
          description:Succès
          content:
            application/json:
              schema:
                type: object
                $ref: "#/components/schemas/Event"
        404:
          description: event not found
    patch:
      tags:
        -un événement
      description:Mise à jour de l'événement
      parameters:
        - name: event_id
          in: path
          description: id
          required: true
          schema:
            type: integer
            format: int64
          example: 1
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  example:Exemple d'événement
      responses:
        200:
          description:Succès
          content:
            application/json:
              schema:
                type: object
                properties:
                  activity:
                    $ref: "#/components/schemas/Event"
    delete:
      tags:
        -un événement
      description:Supprimer l'événement
      parameters:
        - name: event_id
          in: path
          description: id
          required: true
          schema:
            type: integer
            format: int64
            example: 1
      responses:
        204:
          description: No Content
components:
  schemas:
    Event:
      type: object
      properties:
        id:
          description: ID
          type: integer
          format: int64
          example: 1
        title:
          description:Titre
          type: string
          example:Exemple d'événement
        created_at:
          description:Date de création
          type: string
          format: date-time
          example: 2020-04-01 10:00
        updated_at:
          description:Date de mise à jour
          type: string
          format: date-time
          example: 2020-04-01 10:00

L'écran ressemble à ceci:

スクリーンショット 2020-10-25 18.44.00.png

Résumé

Ceci conclut l'introduction de la procédure de création d'un environnement de développement qui intègre l'API et l'interface utilisateur Swagger.

--Combinez l'interface utilisateur et l'API Swagger en utilisant nginx --Créez les paramètres de proxy inverse pour nginx sous "/etc/nginx/conf.d"

Je fais Twitter (@ nishina555). J'espère que vous me suivrez!

Recommended Posts

Créez un environnement de "développement d'API + vérification d'API à l'aide de Swagger UI" avec Docker
Créez un environnement Ruby2.7.x + Rails6.0.x + MySQL8.0.x avec Docker
Créer un environnement de développement PureScript avec Docker
Créer un environnement de développement Wordpress avec Docker
Créer un environnement avec Docker sur AWS
Créer un environnement de développement Ultra96v2 sur Docker 1
Créez rapidement un environnement de développement WordPress avec Docker
[Rails] Comment créer un environnement avec Docker
Comment créer un environnement [TypeScript + Vue + Express + MySQL] avec Docker ~ Vue ~
Environnement Build Rails (API) x MySQL x Nuxt.js avec Docker
Essayez de créer un environnement de développement Java à l'aide de Docker
Créer un environnement Docker avec WSL
Afficher la définition d'API dans l'interface utilisateur Swagger à l'aide de Docker + Rails6 + apipie
Créer un environnement local Couchbase avec Docker
Créer un environnement Node.js avec Docker
Développement de Flink à l'aide de l'API DataStream
Créer un environnement de vérification SolrCloud avec Docker
Créer un environnement de développement Jooby avec Eclipse
Créer un environnement de développement Unity sur docker
Créez un environnement Docker + Laravel avec Laradock
Créer un environnement de développement Go avec WSL2 + Docker Desktop + VSCode (Remote --Containers)
J'ai essayé de créer un environnement de serveur UML Plant avec Docker
J'ai essayé de créer un environnement de développement http2 avec Eclipse + Tomcat
Créer un environnement de test de navigateur à l'aide de Capybara dans l'environnement de développement Docker
Créer un environnement de développement pour Django + MySQL + nginx avec Docker Compose
Construction de l'environnement de développement Laravel avec Docker (Mac)
Créer un environnement de développement Spring Boot-gradle-mysql avec Docker
Créer un serveur proxy d'authentification à l'aide de Docker
[Docker] Construisez l'environnement d'exécution de Jupyter Lab avec Docker
Créer un environnement de vérification des opérations TensorFlow avec Docker
Comment créer un environnement Rails 6 avec Docker
Construction d'un environnement de développement simple Docker + Django
Comment exécuter avec des commandes de langage de développement normales dans l'environnement de développement Docker
[Copier et coller] Créez un environnement de développement Laravel avec Docker Compose, partie 2
Comment créer un environnement pour n'importe quelle version de Ruby en utilisant rbenv
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 6.x)
Créez un environnement de développement local pour les didacticiels Rails avec Docker (Rails 6 + PostgreSQL + Webpack)
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 5.x)
Modèle: créer un environnement de développement Ruby / Rails avec un conteneur Docker (version Ubuntu)
Modèle: créer un environnement de développement Ruby / Rails avec un conteneur Docker (version Mac)
Quand j'ai essayé de créer un environnement pour PHP7.4 + Apache + MySQL avec Docker, je suis resté bloqué [Windows & Mac]
Créer un environnement Laravel / Docker avec VSCode devcontainer