0.0
No release in over 3 years
Low commit activity in last 3 years
Provides a block-based DSL for apidoco similar to ApiPie
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.0
~> 10.0
~> 3.0

Runtime

~> 1.5
 Project Readme

ApidocoDsl

This gem provides a DSL wrapper around the excellent Apidoco Gem for Ruby on Rails projects. The DSL is heavily inspired by the one provided by Apipie, but it was developed from scratch. In our opinion, the Apidoco system is more flexible, and it's output is prettier than Apipie. The one thing it was lacking was a good DSL to produce the JSON files that make up its documentation output. That's where this gem comes in. Instead of writing JSON files by hand, using this gem you can write your documentation directly in to your code as code, which is later parsed and converted into the JSON files that feed the Apidoco engine.

Compatibility with Apidoco

This DSL gem was written against the 1.5.4 version of the Apidoco gem. Later versions of Apidoco may introduce breaking changes with this gem, but we'll do our best to keep it up to date. One important point with regards to compatibility is that this gem renders Apidoco's resource generator, (rails g apidoco resource), unnecessary, unless there really is certain documentation you'd rather write the raw JSON file for. Using this gem, documentation that you write into your code will automatically be placed in the right locations for the Apidoco engine.

Generating documentation

Once you've written your documentation into your code, it has to be parsed and written out to the appropriate Apidoco directory in JSON format. This gem provides a generator for this purpose that is invoked this way:

rails g apidoco_dsl:documentation

Writing Documentation

Where to write it

As mentioned before, this gem allows you to write documentation for your code using code. There are a couple ways you can do this, depending upon the needs of your project and how much you want to intermingle your functional code with your documentation.

Inline with the methods they document

By including the ApidocoDsl module in to the classes you want to document, you can write your documentation in the same file with the code it documents:

class MyApiController < ApplicationController
  require 'apidoco_dsl'
  extend ApidocoDsl

  namespace "V1"
  resource :widgets

  api_doc do
    ...
  end
  def show
    ...
  end
end

In a separate class

Unlike systems like Apipie, with Apidoco and this gem, there is no inherent programmatic link between documentation and the classes/methods being documented. Because of this, it is possible, (and perhaps even preferable), to define all of your documentation in locations and classes that are entirely separate from the code they document. You are free to organize your documentation files however it makes sense to you.

module ApiDocs
  class MyResource
    extend ApidocoDsl
    extend ActiveSupport::Concern

    api_doc do
      ...
    end
  end
end

The DSL

At the most basic level, ApidocoDsl is used for writing documentation about the individual endpoints of your API. Doing so starts with defining an api_doc block. Below is a "full" doc block:

api_doc do
  published true
  name "Do Something"
  description "Does Something"
  endpoint "/v1/do_something/"
  http_method 'POST'
  header({ 'Content-Type' => 'application/json', 'Authentication' => "Bearer <token>" })

  param :thing1, type: 'String',  desc: 'The first thing', notes: "Introduced by the Cat In The Hat", required: true
  param :thing2, type: 'Integer', desc: 'The second thing', notes: "Comes with Thing 1"

  example_request do
    {
      thing1: "This is the first thing",
      thing2: 42
    }
  end

  example_response path: example_root + '/create_response.json'

  returns code: :created do
    property :thing_id, type: 'Integer', desc: "The thing's ID", notes: "Will be a number"
    param_group :carrier_connection_response
  end
end

Note in the example above that example_root is a variable defined above this definition, and not actually part of the ApidocoDsl.

Everything inside the block is considered documentation for the endpoint. It may be helpful to read the Apidoco documentation, for context on some of these, but each method is described below.

published

Whether or not this documentation should be 'published', that is, visible on the documentation site. By default, documentation is not published. Calling this method with an argument of true, will make it visible.

name

This is the name that will be displayed on the documentation page to identify this endpoint, both as a header and in the navigation. It can be anything you want, but obviously should actually identify the endpoint being documented. It takes a string.

description

A longer-form description of the endpoint. This method takes either a string or a path argument. Given a string, it will simply display that string. Given a path, it will parse the provided file, (as Markdown), and use the result as the description for the endpoint.

endpoint

The URL for the endpoint being documented. It will be copied as is into the final documentation for the endpoint. By convention, any parameters provided in the endpoint url are preceded by colons, like this:

endpoint: "v1/customers/:id"

http_method

Which HTTP method(s) to use when calling this endpoint. This is a string that will be passed, as-is to the final documentation. For endpoints that accept more than one method, (PUT or PATCH, for instance), separate them with pipes: PUT|PATCH.

header

What, if any sort of headers to include in the request to this endpoint. Common choices might be a Content-Type header or an Authentication header.

param

This method defines a param for this endpoint. It is discussed in more detail below.

property

Like a param, but generally used to define responses rather than requests. Discussed in more detail below.

param_group

A param_group is used to, literally, group a set of params or properties together. This may be done for simple organizatonal reasons, but it is most useful for creating sets of parameters that can be reused in multiple endpoint definitions. Param groups are discussed in more detail below.

example_request / example_response

There are two ways to provide an example request or an example response for an endpoint. The first is to provide a block to the method itself, adding your example inside:

example_request do
  { "param1": "foo", "param2": "bar" }
end

The hash will be automatically converted to JSON for presentation purposes.

Alternatively, you can provide a path argument that points to a json file:

  example_request path: "/examples/endpoint_request.json"

returns

If your API endpoint returns any properties, the returns method allows you to specify what they are by identifying them as properties:

returns do
  property :response_1, type: "String", desc: "The first part of the response"
  property :response_2, type: "Integer", desc:
end

You can also specify a response code, whether or not the endpoint returns any other properties. If not specified, the code is 200.

  returns code: 203 do
    ...
  end

Params and Properties

Describing which parameters your endpoints take and what properties they return is handled by the param and property methods respectively. These methods work the same way and are technically interchangeable. The only difference is that any defined properties are considered required by default.

Here's an example param:

  param :age, type: 'Integer', desc: "How old this person is.", notes: "Used for setting various interface options", validations: "Must be a positive integer.", required: true

A param/property takes the following attributes:

name

The name of the param/property is the first argument to the method and is always required. Note that it is a positional argument, not a kwarg.

type

A kwarg that describes the "type" of the parameter. If you provide a string, this value can be anything you want. It's also possible to pass any valid Ruby type, (String, Array, Hash, etc.), without enclosing it in a string. The type argument is required.

desc

An optional kwarg that takes a string describing the parameter. For the sake of formatting, it's best if the description is kept relatively short.

notes

An optional kwarg for providing additional context or information about a parameter. For the sake of formatting, it's best if the description is kept relatively short. Notes are an optional means of highlighting specific information about a parameter, (such as acceptable values), etc.

validations

An optional kwarg for adding a note about any validations present on the given parameter. For the sake of formatting, it's best if the validations argument is kept relatively short.

required

Whether or not this parameter is required. Take a boolean and defaults to false for a param and true for a property.

Param Groups

Param groups allow you to define a set of parameters that can be shared between individual documentation blocks, reducing duplication. You define them by calling def_param_group:

  def_param_group :my_group do
    param :param1, type: "Integer", desc: "The first param"
    param :param2, type: "Integer", desc: "The second param"
  end

You can define params or properties inside of a param group just like you would inside of an api_doc block. To add a param group to a doc block, use the param_group method:

  api_doc do
    ...

    param_group :my_group

    ...

    returns do
      param_group :my_response_group
    end
  end

The param_group method takes a single argument, the name of the param group you want to invoke.

Once a param group is defined, it can be used in any documentation block, even those that are in a different source file. For that reason, it may be convenient to define your param groups in files separate from your api documentation itself.

Installation

Add this line to your application's Gemfile:

gem 'apidoco_dsl'

And then execute:

$ bundle

Or install it yourself as:

$ gem install apidoco_dsl

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/apidoco_dsl.

License

The gem is available as open source under the terms of the MIT License.