Ask HN: What's the best way to write an API spec?

170 points by chrisshroba ↗ HN
I'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?

57 comments

[ 3.4 ms ] story [ 128 ms ] thread
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.
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/

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

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...

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!
Great work! I really liked your layouts.
You may find my comment in a related thread interesting: 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.

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/

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

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

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

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

We've (Workday) started using this internally and love it. Thankyou!
This is really cool. Thanks for sharing that!
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...

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.

We love Swagger. It allows us to have uniform documentation across all our APIs regardless of dev writing style. It's a simple plan we can all stick to. Plus it gives you real API access inside the docs themselves. We highly recommend it and may I use this opportunity to thank the developer!
We use Swagger at work. Thanks for this!
use something like capybara or Rspec Testing (rails ) to stimulate a real user behavior
We tried a lot of options at Lavaboom (including apiary, readme.io, swagger, etc) and ended up using Slate: https://github.com/tripit/slate
Can you share some of your reasoning for ending up with Slate?
I would also love to hear a bit more about why you guys chose Slate over the others. Working on API documentation right now for a University, and leaning towards Slate.
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.

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/

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/

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

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

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...

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.

(comment deleted)
I would also point out that API Blueprint allows you to describe your API responses with json schema. They sit at different levels - blueprint for specifying urls resources are accessed with, and json schema for validating the payload.
> 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?

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.
http://www.markus-lanthaler.com/hydra/

My recent choice, w3c track, sensible use case driven progression, growing adoption, flexible embedded or referenced meta-data as appropriate.

I've personally found great joy in being adaptive with the meta data in the responses, like presence of operations and accepted input on the operations depending upon data state and security context, something not really offered with json-schema.

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.

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.

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.

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...
I've really liked using Apiary 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.
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...

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...)

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

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!

I always start "backwards" by writing some example code.
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

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

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.

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.
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.

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.

+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.
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.
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. 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) 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.

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.
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.
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/

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.