
Ask HN: What's the best way to write an API spec? - chrisshroba
I&#x27;m working on a project that contains a REST API, and I want to write out a spec before I start.  Are there tools for this, or should I just make a Google Docs table for it or something?
======
rodw
I guess I'll take this opportunity to plug my own little tool for this.

I use Swagger [1] and more specifically Swagger UI [2] to generate interactive
web-based documentation like the sample at [3].

But rather than relying upon source code annotations to have swagger auto-
generate the documentation, or hand-writing swagger's verbose JSON structure,
I created a little DSL for it as demonstrated at [4] and available on GitHub
at [5].

Let me know if you have any questions about swagger-dsl. It's under-documented
right now but perfectly functional. I use it often.

[1] [http://swagger.io/](http://swagger.io/)

[2] [https://github.com/swagger-api/swagger-ui](https://github.com/swagger-
api/swagger-ui)

[3]
[http://petstore.swagger.wordnik.com/#!/pet](http://petstore.swagger.wordnik.com/#!/pet)

[4] [http://intellinote.github.io/swagger-
dsl/demo/live.html](http://intellinote.github.io/swagger-dsl/demo/live.html)

[5] [https://github.com/intellinote/swagger-
dsl](https://github.com/intellinote/swagger-dsl)

~~~
matt_kantor
BTW, Swagger-codegen has [support for writing specs in YAML][1] too, if that's
your thing.

My team makes uses generated Swagger API docs (via the swagger-play2 plugin),
but to be honest the tooling around it is pretty half-assed. Having a machine-
readable spec is a game changer, though.

[1]: [https://github.com/swagger-api/swagger-
codegen/wiki/Creating...](https://github.com/swagger-api/swagger-
codegen/wiki/Creating-Swagger-JSON-from-YAML-files)

~~~
rodw
Thanks Matt.

I looked at swagger-codegen before createing swagger-dsl, and frankly it is
pretty nice, but with respect to authoring the underlying Swagger
specification document, swagger-codegen is just a direct YAML translation of
the original Swagger JSON format.

In other words, swagger-codegen's YAML support is just a YAML-to-JSON
transformation. It has the same redundancies and structural issues as
Swagger's JSON, just in a YAML syntax.

My objective with swagger-dsl was to create a more human-oriented (more
readable, less verbose, less error prone, more DRY, etc.) format for authoring
those JSON documents for Swagger. It's not just JSON-as-YAML, it's a more
author-oriented (as opposed to parser-oriented) way to describe the API.

------
gamache
There have been an explosion of API specification formats in the last few
years. No clear winner has emerged.

JSON Schema and JSON Hyperschema are JSON-based formats for describing JSON
and REST (hypermedia-driven) APIs. The formats make decent sense and can be
used to generate docs, validators, client libraries, UIs, and more.
[http://json-schema.org/](http://json-schema.org/)

API Blueprint is another emerging format for API description. It's written in
Markdown, so it is very human-readable and -writable. It is not yet suitable
for hypermedia APIs. Like JSON Schema, its tooling includes validators, client
library generators, mock server generators, docs generators, etc.
[http://apiblueprint.org/](http://apiblueprint.org/)

Swagger is a YAML-based format for specifying JSON APIs. It is meant to be
created using the Swagger UI, rather than handwritten. It generates pretty
docs, client software, etc. but is not suited to describing hypermedia APIs.
[http://swagger.io](http://swagger.io)

Slate is an API documentation framework/template, designed to generate very
handsome documentation pages. Its concern is more documentation than
specification, and therefore doesn't concern itself with things like library
or mock generation.
[https://github.com/tripit/slate](https://github.com/tripit/slate)

WADL is an API description language which describes API interactions in an XML
format. It resembles WSDL. Not many people use it.
[http://en.wikipedia.org/wiki/Web_Application_Description_Lan...](http://en.wikipedia.org/wiki/Web_Application_Description_Language)

Which of these is the best? Good question. I like JSON Hyperschema, but I am
writing hypermedia APIs and the other formats here are lacking in their
hypermedia support. API Blueprint is a nice format to write in a text editor
and is easily read as-is or rendered from Markdown; no separate docs generator
is necessary.

~~~
Flenser
> Swagger ... is not suited to describing hypermedia APIs

Why is that? It wouldn't force/guide you to create a hypermedia APIs by
default, but it could be used to document one couldn't it?

~~~
gamache
At least the last time I looked at Swagger, it was very much URL/endpoint-
focused. Hyperlinks, while documentable, are not first-class citizens. In a
real hypermedia-driven API, you want to document the links, not the URLs, as
the API users will be using these named links, and not constructing URLs, to
access functionality.

------
deeviant
There is no single secret to making good API specifications.

But here are few things I've learned:

* The more comprehensive the documentation gets, the the quicker it gets outdated, un-useful, or flat out pants-on-fire lying. Define what the thing does and what assumptions are made, save detail for "gotchas". Be concise.

* Start out on a white board, run through each function, what it should do, what it shouldn't. This really is a huge benefit of spec'ing out a api, just sitting there thinking about it, tons of stuff comes up and you come out with a better product in the end.

* If the format you came up with can't be put into something like a table or spreadsheet, you probably doing it wrong. Sure you can get some sort of framework that lets you create all sorts of UML and create class/function shells or what have you, but I have never found these to create value or clarity. If you are spending more than 20-30 minutes outlining even a complicated function, your probably wasting time. Use time saved to create a clear system-wide DFD.

* Don't go deep into implementation detail at this stage, but at least think about it. Some much time can be saved with a little forethought here.

------
DevX101
I used apiary.io which is the best tool I've found for writing API specs. You
can write your specs using an online API Blueprint format editor via their
site. Alternatively, you can put a text file in your repo and authorize apiary
to pull the file every time you make a commit to github. This way you do
everything via your development environment.

The documentation they provide based on the specs looks very well designed and
intuitive.

One of my favorite features about apiary was the mock backend server they use
based on my API specs. So if you're doing a single page app, just write your
specs then point your frontend app to the mock server they provide. This
greatly simplified development process for me.

------
davnola
Here's a summary of the discussion (RAML vs Swagger vs Apiary vs RSpec...) we
had at Lonely Planet:
[https://lonelyplanet.atlassian.net/wiki/display/PUB/API+Spec...](https://lonelyplanet.atlassian.net/wiki/display/PUB/API+Specification%2C+Automated+Testing%2C+and+Documentation+Generation+Discussion)

5 months in, we're happy with API Blueprint. We used to use Dredd for API
validation but ran into to some limitations:

\- Dredd does not perform any validation against the siren response beyond the
first key level. For example, it does not validate if the class-name is user-
events, or usr-events

\- Dredd does not make any difference between Action parameters and Resource
parameters. Then, an action POST to create user-events will have undesired url
parameters. E.G: POST /user-events?take=0&skip=2 (The apib blueprint specs
allows to make this difference: [https://github.com/apiaryio/api-
blueprint/blob/master/exampl...](https://github.com/apiaryio/api-
blueprint/blob/master/examples/7.%20Parameters.md#all-my-messages-
messageslimit))

So one of our devs created a Ruby validator,
[https://github.com/nogates/vigia](https://github.com/nogates/vigia). See
[http://engineering.lonelyplanet.com/2014/11/18/vigia-
integra...](http://engineering.lonelyplanet.com/2014/11/18/vigia-integration-
tests.html) if you're interested.

~~~
netmilk
Hi, I'm Dredd developer and here are my comments on Dredd - API Blueprint
testing tool:

\- Dredd does not perform any validation against the siren response beyond the
first key level. For example, it does not validate if the class-name is user-
events, or usr-events

This I can't confirm, presence of object keys is validated on any level.

\- Dredd does not make any difference between Action parameters and Resource
parameters. Then, an action POST to create user-events will have undesired url
parameters. E.G: POST /user-events?take=0&skip=2

This is true, but it’s by design. In Dredd URI parameters are inherited from
resource to action, but there is no way how to filter out unwanted parameters
from resource under action section.

In this case I assume that `skip` and `take` parameters belong only to GET
action (retrieving collection), so its imho a non-sense to discuss them on the
resource level because they will be propagated to any action under that
resource.

Thank you for very interesting feedback!

------
pksunkara
Disclaimer: I work for Apiary.

API Blueprint [1] is an open source API description format which can be used
to intuitively describe an API.

MSON [2] is a recent addition to the above format which makes it easy to
describe all kinds of complex requests and responses in the spec.

You can email me at pavan [at] apiary [dot] io if you have any more questions.

[1]: [http://apiblueprint.org](http://apiblueprint.org)

[2]: [http://github.com/apiaryio/mson](http://github.com/apiaryio/mson)

------
Erwin
Like others, I use the Apiary's Markdown format, using aglio to generate a
HTML page from it. I also use Protagonist to convert the documentation to a
JSON object that Python code can consume and verify that there's a 1:1
relationship between documented and implement API endpoints, as well as as
arguments passed. There's room for further validation as my API endpoints have
type checking and permissions declaratively configured (via Python
decorators).

I tried RAML -- it makes sense for quick prototyping of your resources and
methods, but I oculdn't see myself writing too much documentation as a giant
nested YAML document.

I also tried apidoc which might make sense of you have internal documentation
you wan to quickly expose. However my docs are longer than the code
implementing them, so I don't like mixing them in as e.g. apidoc would
require. I'd prefer lots of English in my documentation and it seems odd to
conflate hints on how to use an API call as an external user with the
implementation of it. Compare Sphinx-generated Python docs with some auto-
generated python library documentation.

The apidoc versioning system is pretty cool, though if you are making a public
REST API backwards-incompatible version changes should be avoided.

------
dkarapetyan
Write some client code for how you want to use the API and then elaborate
those examples by making references to the spec. This might seem backwards to
you but you'll discover all sorts of edge cases and awkwardness in the process
that you wouldn't have discovered by just writing the spec.

You don't need any special tools to do that although apiary comes to mind as
something worthwhile.

~~~
blt
+1 on starting with use cases. Write the client code you'd love to write, and
then figure out what API will make it possible.

------
smt88
Have a look at [http://apiary.io](http://apiary.io) and
[http://readme.io](http://readme.io)

~~~
gdillon
Hey, thanks for the tip. ReadMe.io cofounder here, happy to answer any
questions about my service or API specs in general.

ReadMe.io currently focuses more on the "front end" of the API. We can ingest
in-line comments made with the apiDoc.js [1] standard, and then use that
description to build an API explorer and reference docs automatically. We like
apiDoc because of how concise the comments are, and because they are kept very
close to the code (no extra files to maintain). It's not as common as some of
the other standards mentioned here, but it's — by far — the fastest and most
straightforward way to describe an API.

[1] [http://apidocjs.com/](http://apidocjs.com/)

Edit: this is how it's implemented within ReadMe.io: [http://readme-
sync.readme.io/v1.0/docs](http://readme-sync.readme.io/v1.0/docs)

~~~
smt88
I like apiDoc, too, and I spent a few days adding those comments to my code.

However, it's been months now, and the GitHub Sync section still says
"temporarily disabled".

Is this feature really done? When can I use it?

I'm a bootstrapper and understand testing features by pretending they exist,
but it's been a pretty long time...

~~~
gdillon
Hah, touché. It's 98% done and only requires a little bit of usability polish
before going live. You can shoot me a note (support [at] readme.io) with your
project subdomain and I can enable it for you. Appreciate it!

------
xiaoma
1) The best tool is probably RAML. It's very succinct, looks like YAML and has
powerful features such as traits that really simplify the process of
documenting many endpoints with similar traits (e.g. pagination).
[http://raml.org/](http://raml.org/)

2) Swagger is an older option that is quite verbose but has a lot of good
tooling support.

3) A third tool that is pretty decent is API blueprint.

Disclosure: I did work on an open source swagger-raml converter about four
months ago.

------
jobu
After working on a couple API's used by mobile devices I would recommend
starting with some static pages containing JSON, then write a client against
them first. That will help verify that you have all of the needed data and the
format is correct.

Once the format is nailed down it's easier to write documentation, and the
server side code will go quickly because less time is spent iterating changes.

------
phipz
We used to start with Aglio
([https://github.com/danielgtaylor/aglio](https://github.com/danielgtaylor/aglio))
and the API Blueprint format 1A ([https://github.com/apiaryio/api-
blueprint](https://github.com/apiaryio/api-blueprint)) provided by Apiary. We
recently moved from Aglio to Apiary.

------
yogiHacks
I've really liked using Apiary [http://apiary.io/](http://apiary.io/) It lets
you build sample output and URI address for your API's, document multiple
routes, and stores everything nicely on your account on their cloud. I've used
it for 2 projects this year already and have really liked it.

------
debacle
Writing tests for your spec is probably the best way. You get to test the
design of your API (and any edge cases/scaling issues) before you actually
have to design it, and, bonus, when you're done you have a full suite of
tests.

------
simi_
We tried a lot of options at Lavaboom (including apiary, readme.io, swagger,
etc) and ended up using Slate:
[https://github.com/tripit/slate](https://github.com/tripit/slate)

~~~
simi_
We ended up with Slate because:

1\. readme.io is just painful to use for larger documentations; very GUI-
oriented 2\. apiary is basically just annoying in every way (I really like the
company so I tried 3 separate times to get myself to like their product) 3\. I
dismissed a couple of self-hosted options that use JS to render the
information, since I find that idiotic

Slate struck a good balance between (1) syntax (2) ease of use and (3) good
looks, although I wouldn't call it prefect in any of those departments.

Disclaimer: the end result looks surprisingly better than what you'd expect.

------
kikibobo69
My former colleagues have been working on
[http://apidoc.me/](http://apidoc.me/)
([https://github.com/gilt/apidoc](https://github.com/gilt/apidoc)). I really
like this approach, which is basically:

1\. specify the api in json 2\. apidoc generates really nice api documentation
3\. apidoc generates a single-file client for the service (currently ruby or
scala) 4\. apidoc generates a routes file for play2

It's scala-biased at the moment because that's their tech stack, but in
practice an api-first approach seems to lead to higher quality APIs compared
to just hacking something together and annotating it to extract docs. Also
having a really nice client without a complicated compile-time dependency
graph (on the JVM) feels like a sweet spot.

------
prabhatjha
My vote is definitely for swagger. Besides being a great way to write API
spec, it has tons of tooling to take a given spec to the next level. See the
list at [https://github.com/swagger-api/swagger-
spec](https://github.com/swagger-api/swagger-spec). My favorite is Swagger
Editor which allows you to write a spec in YAML and shows you consumable API
in real time.

There also exist an opens source project that has Swagger at its core called
a127
([https://github.com/apigee-127/a127-documentation/wiki](https://github.com/apigee-127/a127-documentation/wiki))
that allows you to build enterprise-class APIs in Node.js locally and deploy
to any PaaS where you can run a node app.

 __Disclaimer: I work with a127 project.

------
jestar_jokin
Isn't this why enterprises favoured things like SOAP web services with XSDs
and WSDLs? The verbosity acts as human and machine-readable documentation, and
the files can be used to generate client code.

Ignoring the benefits of using HTTP as the request transport mechanism, this
seems like another cycle of people coming up with a comprehensive but complex
solution, other people getting frustrated with the complexity and developing a
simpler solution, then filling in the gaps (such as documentation) until the
solution is a complex patchwork of competing libraries, none clearly better
than the others, leading to fragmenting of mindshare and expertise...

------
monkeypodio
At Willowtree, we created Monkeypod
([https://Monkeypod.io](https://Monkeypod.io)) to serve as an API design,
documentation and virtualization tool.

It uses Swagger and swagger ui extensively and can output (and soon input)
Swagger specs. It creates a virtual API based on the design you create, and
you can play with it from Swagger ui sandbox or any Http client.

We have a lot of cool features on the roadmap. Feel free to sign up and give
it a try. Let us know what features you'd like to see. Cheers!

------
mrkd
It looks like there are some options out there for REST APIs.

Does anyone know of any API specs written for websocket APIs?

I am working on creating a websocket API and would like to at least look at a
few other examples.

~~~
sv3nss0n
This is something I am looking for as well. In my case I'd like to integrate a
REST API with a Push Notifications API in a unified API specification. Today I
have resorted to using JSON schemas/hyperschemas with custom templating using
the Heroku's prmd tool. Works ok but has the drawback that it relies on my
custom made templates...

------
z3t4
I always start "backwards" by writing some example code.

------
pedrobelo
I wrote about a few of the different formats before:
[http://pedro.by4am.com/past/2014/5/23/get_more_out_of_your_s...](http://pedro.by4am.com/past/2014/5/23/get_more_out_of_your_service_with_machinereadable_api_specs/)

And been working on a tool to merge the schema with actual code for Sinatra
apps: [https://github.com/pedro/sinatra-
schema](https://github.com/pedro/sinatra-schema)

------
andrewstuart
Regardless of solution chosen, Swagger or otherwise, I'm puzzled as to why
people integrate the API spec/documentation into their source code. Seems to
me to provide incredible scope for bugs and dramatically increase software
complexity: [http://fourlightyears.blogspot.com.au/2015/01/swagger-is-
gre...](http://fourlightyears.blogspot.com.au/2015/01/swagger-is-great-but-
integrating.html)

------
conorgil145
You may find my comment in a related thread interesting:
[https://news.ycombinator.com/item?id=8847072](https://news.ycombinator.com/item?id=8847072)

I was discussing my interest in documenting an API and then generating client
libraries, API tests, and other artifacts automatically. Some relevant tools
and projects were mentioned/discussed.

------
liamcode
I use [http://apidocjs.com/](http://apidocjs.com/)

You define the API in comments within your code. When you run apidoc it scans
your code and generates pretty documentation.

I tried various other solutions before this such as apiary.io. Apidocjs is
really easy to update as it is part of your code, which also means it goes
into your version control!

------
jlouvel
Restlet Studio ([http://studio.restlet.com/](http://studio.restlet.com/))
let's you visually craft your REST API and then view it as Swagger 2.0 or RAML
0.8 source code by simply switching tabs.

It is entirely free and available as a simple web app and installable as a
Chrome app. Disclaimer: I work at Restlet.

------
ioseph
We've just started designing a new api and gone done the json-schema path
which is particularly suitable since we're using json-rpc over websocket /
http post.

Aside from that whatever tool you use, having markdown as the base source is
really useful as you can then display it however you want while still quickly
read it in a terminal.

------
sm_sohan
May I say, look at SpyREST (SpyREST.com) if you consider developing the API
first and then produce the documentation automatically simply by exercising
the API? This is an open-source tool, feel free to take a look.

I'm developing SpyREST and will be happy to discuss if you want to learn more.

------
marcoherbst
I can't be entirely sure that it's to do with the tools used (I'm familiar
with most of the ones mentioned in the comments) but my most successful API
designing, at a high level, has been in a spreadsheet.

------
dreamdu5t
Why not model your REST resources so that API documentation can be auto-
generated from your actual code? Makes a lot more sense to me than trying to
generate code from documentation.

------
eterps
I use Cucumber to write the API spec for our hypermedia API, it doubles as an
end-to-end test which guarantees that the specs are never out of sync with our
API implementation.

------
kephra
I would follow the RFC and the Unix manual layout. I normally use XML to write
my documentation, and simple xslt to convert them to roff to produce
text/plain and pdf and html.

------
haidrali
use something like capybara or Rspec Testing (rails ) to stimulate a real user
behavior

