Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: What's the best way to write an API spec?
170 points by chrisshroba on Jan 19, 2015 | hide | past | favorite | 56 comments
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?



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 been working on updating our API to V2[1], and decided to go with grape because it automatically generates documentation via grape-swagger[2].

Initially we considered Apiary, but we wanted more flexibility and preferred to host things ourselves. And the fact that our documentation is generated automatically from the code via grape-swagger is a game changer.

[1] https://bikeindex.org/documentation/api_v2

[2] https://github.com/tim-vandecasteele/grape-swagger


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!


We've (Workday) started using this internally and love it. Thankyou!


This is really cool. Thanks for sharing that!


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.


Yet another relatively new definition format: http://raml.org/


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


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


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!


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


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.


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.



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.


+1 point for apiary.io


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.


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.


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


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.


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.


We tried a lot of options at Lavaboom (including apiary, readme.io, swagger, etc) and ended up using Slate: https://github.com/tripit/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.


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.


My former colleagues have been working on http://apidoc.me/ (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.


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.


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


At Willowtree, we created Monkeypod (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!


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


I wrote about a few of the different formats before: http://pedro.by4am.com/past/2014/5/23/get_more_out_of_your_s...

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


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


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 use 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!


Restlet Studio (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.


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.


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.


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.


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


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.


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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: