Search code examples
ruby-on-railsswaggerswagger-uiactive-model-serializers

Swagger UI for Rails API using ActiveModel's Serializer


I was wondering if anyone's done this before where they generate API docs using Swagger UI for an API not also generated by Swagger. Here's what a simple example of mine looks like:

class Api::V1::UsersController < Api::V1::BaseController
  swagger_controller :users, 'Users'

  swagger_api :show do
    summary 'Returns a user'
    param :path, :id, :integer, :optional, "User Id"
    notes '/api/v1/users/:id'
    response :ok, "Success", :Users
    response :unauthorized
    response :not_acceptable
    response :not_found
  end

  def show
    user = User.find(params[:id])

    render(json: Api::V1::UserSerializer.new(user).to_json)
  end
end

I've generated the swagger docs with rake swagger:docs and can reach http://localhost:3000/api-docs.json just fine where I see the documentation for Users#show, but when I click "Try it out!", I get a missing template error for api/v1/users/show

enter image description here


api-docs.json:

{
  "apiVersion": "1.0",
  "swaggerVersion": "1.2",
  "basePath": "http://localhost:3000",
  "apis": [
    {
      "path": "/api/v1/users.{format}",
      "description": "Users"
    }
  ],
  "authorizations": null
}

users.json:

{
  "apiVersion": "1.0",
  "swaggerVersion": "1.2",
  "basePath": "http://localhost:3000",
  "resourcePath": "users",
  "apis": [
    {
      "path": "/api/v1/users/{id}.json",
      "operations": [
        {
          "summary": "Returns a user",
          "parameters": [
            {
              "paramType": "path",
              "name": "id",
              "type": "integer",
              "description": "User Id",
              "required": false
            }
          ],
          "notes": "/api/v1/users/:id",
          "responseMessages": [
            {
              "code": 200,
              "responseModel": "Users",
              "message": "Success"
            },
            {
              "code": 401,
              "responseModel": null,
              "message": "Unauthorized"
            },
            {
              "code": 404,
              "responseModel": null,
              "message": "Not Found"
            },
            {
              "code": 406,
              "responseModel": null,
              "message": "Not Acceptable"
            }
          ],
          "nickname": "Api::V1::Users#show",
          "method": "get"
        }
      ]
    }
  ],
  "authorizations": null
}

How can I render the correct response for my show method so that it looks for the serialized json rather than a view file?


Solution

  • So, I found the answer. First, delete all the json files created by rake swagger:docs and add into the swagger_docs.rb initializer the following: :clean_directory => true so that everytime rake swagger:docs is run, the directory in public folder is cleared.

    In order for swagger docs to work with how I'm building my API with ActiveModel's Serializers is to change up the DSL written in Api::V1::UsersController, like so:

      swagger_api :show do
        summary 'Returns a user'
        param :path, :id, :integer, :optional, "User Id"
        notes '/api/v1/users/:id'
      end
    

    then run rake swagger:docs and the call to show a user should work fine.