Docker+Rails6+apipie를 사용하여 API 정의를 Swagger UI에 표시

목표


  • API 정의가 쓰여진 파일을 자동 생성한다
  • docker-compose에서 Swagger UI의 컨테이너 관리
  • 로컬 환경의 Swagger UI에서 API 정의를 탐색하고 요청/응답합니다.

    환경


    Ruby: 2.7.1
    Rails: 6.0.3
    

    1. API 정의가 작성된 파일 자동 생성



    소개



    apipie-rails 이라고 하는 gem으로 API 정의 파일을 생성할 수 있을 것 같았으므로, 이쪽을 사용했습니다.

    Getting started에 따라 Gemfile에 추가하거나 apipie를 초기화합니다.

    Gemfile
    gem "apipie-rails"
    
    $ bundle install
    $ rails g apipie:install
    
    apipie.rb 의 생성, routes.rbapipie 의 추가가 행해집니다.

    문서 작성



    DSL 참조 을 바탕으로 각 Controller의 메소드 상단에 API 정의를 작성합니다.
    (여기는 자작...)

    다음은 구현 예

    api/v1/users_controller.rb
    class Api::V1::UsersController < ApiController
    
      api :POST, "/api/v1/users/token", "get access token"
      description "ログイン認証をしてトークンを返す"
      formats ["json"]
      param :email, String, desc: "メールアドレス", required: true
      param :password, String, desc: "パスワード", required: true
      returns code: 200, desc: "return user token"
      error code: 401, desc: "Unauthorized"
      example <<-JSON
        {
          detail: "Token Example",
        }
      JSON
    
      def token
        # 実装略
      end
    

    API 정의 파일 생성


    $ rails apipie:static_swagger_json
    
    doc/apidocschema_swagger_form_data.json 가 생성됩니다.

    2. docker-compose에서 Swagger UI의 컨테이너 관리



    docker-compose 설정



    docker-compose.yml
    services:
      app:
       (略)
    
      swagger-ui:
        image: swaggerapi/swagger-ui
        ports:
          - "8081:8080"
        volumes:
          - doc/apidoc/schema_swagger_form_data.json:/swagger.json
        environment:
          SWAGGER_JSON: /swagger.json
    

    docker를 시작하고 localhost:8081에 액세스하면 API 정의를 읽을 수 있습니다.



    참고 : Swagger Editor와 Swagger UI를 Docker로 이동

    apipie.rb 조정



    프로젝트에 따라 디렉토리 구성과 포트가 다르므로 필요에 따라 apipie.rb를 조정하십시오.
    이쪽도 자세한 것은 레퍼런스 Swagger-Specific Configuration Parameters 에 실려 있습니다.

    apipie.rb
    -  config.api_base_url            = "/api"
    +  config.api_base_url            = ""
    +  config.swagger_api_host = "localhost:3100"
    

    조정 후에는 문서 생성을 잊지 마세요.

    3. 로컬 환경의 Swagger UI에서 API 정의 탐색 및 요청/응답 수행



    현재 설정은 API와 Swagger UI의 컨테이너가 다르므로 API 요청/응답을 할 수 없습니다.
    해결하기 위해 CORS를 설정합니다.

    CORS 설정



    rack-cors gem을 추가하고 다음과 같이 설정을 추가합니다.

    Gemfile
    gem "rack-cors"
    

    config/application.rb
    module App
      class Application < Rails::Application
        (中略)
    
        # 以下を追加
        config.x.request = ActiveSupport::InheritableOptions.new(config_for(:request))
    
        # Permit cross origin
        config.middleware.insert_before 0, Rack::Cors do
          allow do
            origins Rails.application.config.x.request["domain"]
            resource "*",
            headers: :any,
            methods: [:get, :post, :put, :patch, :delete, :options, :head]
          end
        end
      end
    end
    

    config/request.yml
    default: &default
      domain:
       - localhost:3100 # appのport
       - localhost:8081 # swagger-uiのport
    
    development:
      <<: *default
    
    test:
      <<: *default
    
    production:
      domain:
    
    
    

    다시 쓰면 app 컨테이너를 restart하면 Swagger UI에서 요청을 할 수 있습니다.

    참고:
    - Swagger-UI에서 TypeError : Failed to fetch가 나와 죽음
    - CORS 설정을 환경별로 구분
  • 좋은 웹페이지 즐겨찾기