Coder Social home page Coder Social logo

api-standards's Introduction

18F API Standards

18F is a technology team inside the US federal government. 18F is very API-focused: our first project was an API for business opportunities.

This document captures 18F's view of API best practices and standards. We aim to incorporate as many of them as possible into our work.

APIs, like other web applications, vary greatly in implementation and design, depending on the situation and the problem the application is solving.

This document provides a mix of:

  • High level design guidance that individual APIs interpret to meet their needs.
  • Low level web practices that most modern HTTP APIs use.

Design for common use cases

For APIs that syndicate data, consider several common client use cases:

  • Bulk data. Clients often wish to establish their own copy of the API's dataset in its entirety. For example, someone might like to build their own search engine on top of the dataset, using different parameters and technology than the "official" API allows. If the API can't easily act as a bulk data provider, provide a separate mechanism for acquiring the backing dataset in bulk.
  • Staying up to date. Especially for large datasets, clients may want to keep their dataset up to date without downloading the data set after every change. If this is a use case for the API, prioritize it in the design.
  • Driving expensive actions. What would happen if a client wanted to automatically send text messages to thousands of people or light up the side of a skyscraper every time a new record appears? Consider whether the API's records will always be in a reliable unchanging order, and whether they tend to appear in clumps or in a steady stream. Generally speaking, consider the "entropy" an API client would experience.

Using one's own API

The #1 best way to understand and address the weaknesses in an API's design and implementation is to use it in a production system.

Whenever feasible, design an API in parallel with an accompanying integration of that API.

Point of contact

Have an obvious mechanism for clients to report issues and ask questions about the API.

When using GitHub for an API's code, use the associated issue tracker. In addition, publish an email address for direct, non-public inquiries.

Notifications of updates

Have a simple mechanism for clients to follow changes to the API.

Common ways to do this include a mailing list, or a dedicated developer blog with an RSS feed.

API Endpoints

An "endpoint" is a combination of two things:

  • The verb (e.g. GET or POST)
  • The URL path (e.g. /articles)

Information can be passed to an endpoint in either of two ways:

  • The URL query string (e.g. ?year=2014)
  • HTTP headers (e.g. X-Api-Key: my-key)

When people say "RESTful" nowadays, they really mean designing simple, intuitive endpoints that represent unique functions in the API.

Generally speaking:

  • Avoid single-endpoint APIs. Don't jam multiple operations into the same endpoint with the same HTTP verb.
  • Prioritize simplicity. It should be easy to guess what an endpoint does by looking at the URL and HTTP verb, without needing to see a query string.
  • Endpoint URLs should advertise resources, and avoid verbs.

Some examples of these principles in action:

Just use JSON

JSON is an excellent, widely supported transport format, suitable for many web APIs.

Supporting JSON and only JSON is a practical default for APIs, and generally reduces complexity for both the API provider and consumer.

General JSON guidelines:

  • Responses should be a JSON object (not an array). Using an array to return results limits the ability to include metadata about results, and limits the API's ability to add additional top-level keys in the future.
  • Don't use unpredictable keys. Parsing a JSON response where keys are unpredictable (e.g. derived from data) is difficult, and adds friction for clients.
  • Use consistent case for keys. Whether you use under_score or CamelCase for your API keys, make sure you are consistent.

Use a consistent date format

And specifically, use ISO 8601, in UTC.

For just dates, that looks like 2013-02-27. For full times, that's of the form 2013-02-27T10:00:00Z.

This date format is used all over the web, and puts each field in consistent order -- from least granular to most granular.

API Keys

These standards do not take a position on whether or not to use API keys.

But if keys are used to manage and authenticate API access, the API should allow some sort of unauthenticated access, without keys.

This allows newcomers to use and experiment with the API in demo environments and with simple curl/wget/etc. requests.

Consider whether one of your product goals is to allow a certain level of normal production use of the API without enforcing advanced registration by clients.

Error handling

Handle all errors (including otherwise uncaught exceptions) and return a data structure in the same format as the rest of the API.

For example, a JSON API might provide the following when an uncaught exception occurs:

{
  "message": "Description of the error.",
  "exception": "[detailed stacktrace]"
}

HTTP responses with error details should use a 4XX status code to indicate a client-side failure (such as invalid authorization, or an invalid parameter), and a 5XX status code to indicate server-side failure (such as an uncaught exception).

Pagination

If pagination is required to navigate datasets, use the method that makes the most sense for the API's data.

Parameters

Common patterns:

  • page and per_page. Intuitive for many use cases. Links to "page 2" may not always contain the same data.
  • offset and limit. This standard comes from the SQL database world, and is a good option when you need stable permalinks to result sets.
  • since and limit. Get everything "since" some ID or timestamp. Useful when it's a priority to let clients efficiently stay "in sync" with data. Generally requires result set order to be very stable.

Metadata

Include enough metadata so that clients can calculate how much data there is, and how and whether to fetch the next set of results.

Example of how that might be implemented:

{
  "results": [ ... actual results ... ],
  "pagination": {
    "count": 2340,
    "page": 4,
    "per_page": 20
  }
}

Always use HTTPS

Any new API should use and require HTTPS encryption (using TLS/SSL). HTTPS provides:

  • Security. The contents of the request are encrypted across the Internet.
  • Authenticity. A stronger guarantee that a client is communicating with the real API.
  • Privacy. Enhanced privacy for apps and users using the API. HTTP headers and query string parameters (among other things) will be encrypted.
  • Compatibility. Broader client-side compatibility. For CORS requests to the API to work on HTTPS websites -- to not be blocked as mixed content -- those requests must be over HTTPS.

HTTPS should be configured using modern best practices, including ciphers that support forward secrecy, and HTTP Strict Transport Security. This is not exhaustive: use tools like SSL Labs to evaluate an API's HTTPS configuration.

For an existing API that runs over plain HTTP, the first step is to add HTTPS support, and update the documentation to declare it the default, use it in examples, etc.

Then, evaluate the viability of disabling or redirecting plain HTTP requests. See GSA/api.data.gov#34 for a discussion of some of the issues involved with transitioning from HTTP->HTTPS.

Server Name Indication

If you can, use Server Name Indication (SNI) to serve HTTPS requests.

SNI is an extension to TLS, first proposed in 2003, that allows SSL certificates for multiple domains to be served from a single IP address.

Using one IP address to host multiple HTTPS-enabled domains can significantly lower costs and complexity in server hosting and administration. This is especially true as IPv4 addresses become more rare and costly. SNI is a Good Idea, and it is widely supported.

However, some clients and networks still do not properly support SNI. As of this writing, that includes:

  • Internet Explorer 8 and below on Windows XP
  • Android 2.3 (Gingerbread) and below.
  • All versions of Python 2.x (a version of Python 2.x with SNI is planned).
  • Some enterprise network environments have been configured in some custom way that disables or interferes with SNI support. One identified network where this is the case: the White House.

When implementing SSL support for an API, evaluate whether SNI support makes sense for the audience it serves.

Use UTF-8

Just use UTF-8.

Expect accented characters or "smart quotes" in API output, even if they're not expected.

An API should tell clients to expect UTF-8 by including a charset notation in the Content-Type header for responses.

An API that returns JSON should use:

Content-Type: application/json; charset=utf-8

CORS

For clients to be able to use an API from inside web browsers, the API must enable CORS.

For the simplest and most common use case, where the entire API should be accessible from inside the browser, enabling CORS is as simple as including this HTTP header in all responses:

Access-Control-Allow-Origin: *

It's supported by every modern browser, and will Just Work in many JavaScript clients, like jQuery.

For more advanced configuration, see the W3C spec or Mozilla's guide.

What about JSONP?

JSONP is not secure or performant. If IE8 or IE9 must be supported, use Microsoft's XDomainRequest object instead of JSONP. There are libraries to help with this.

Public domain

This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.

All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.

api-standards's People

Contributors

adelevie avatar arowla avatar bengm avatar carloseberhardt avatar gbinal avatar gplocke avatar jabley avatar jrep avatar konklone avatar leahbannon avatar lenatrudeau avatar lindsayyoung avatar monfresh avatar noahkunin avatar paulswartz avatar philipashlock avatar readmecritic avatar traviscarden avatar wardi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api-standards's Issues

JSON as a default

JSON isn't the end-all be-all, and hopefully an even better format comes along in the next 10 years, but I suspect we're all going to be defaulting our APIs to use it for a long while.

And if we're also saying don't support multiple formats, then it only makes sense to say JSON is a good place to start, if you don't have strong feelings or specific requirements.

With JSON, always return an object

Returning an array ([]) reduces flexibility in including metadata about the response alongside the response itself (e.g. pagination information). Using an object ({}) and putting any "results" into an array field on that object is a better practice.

What data should go in headers, and what data in the response body

From an HN comment:

First off: Because this functionality is in HTTP spec itself, I believe it should be leveraged when it makes sense. Otherwise, why even bother with HTTP and response codes?

Secondly, because you don't need to parse a JSON response to make decisions based on the response, both clients and servers can potentially be simpler and faster. If you got a 206 response and 1000 items back, but you made the request without an accept range header, not knowing if you were going to receive 10 items or 10000 items, you don't need to parse the JSON to find this out.

This is opposed to just retrieving a 200 response, parsing and processing 1000 items, getting to the end to find a "next" property in your JSON you weren't expecting, and then firing off another request, when you could have already queued a second request if you had read the header first before processing your response. (RFC2616 Section 3.12 gives you some leverage in specifying range units, so its easy to define the range in items instead of bytes.)

However, I don't think that creating new headers is a good idea. My recommendation is simple: If it's in the HTTP spec and you are can use it according to how it's defined (like my items range example), then you should use it. If it's not in the spec, just go ahead and put it in the URI/response. The exceptions to that is maybe custom authentication mechanisms (i.e. HMAC or cookie based authentication), or anything which may be performance sensitive. For example, I have endpoints that are used in browser and by batch machines. It's easy to just use cookies for the browser and HMAC for batch machines.

This seems like it's in the grey area between standard and recommendation, but what does everyone think? cc @konklone @GUI

Data envelopes and format of `results` attribute

Over on 18F/team-api1, we were having a discussion about whether to return results as an object or an array. We (@mbland, @monfresh, @jmcarp and @arowla) were generally in agreement that the results should return as an array. However, @jmcarp brought up the issue that the highest level of results returned needs to be an object, to avoid a JSON vulnerability2. To that end, we decided that team-api needs to wrap returned data in an envelope object and include a results attribute that is an array.

We'd like to suggest that the api-standards document should address JSON envelopes and result arrays in the "Just Use JSON" section3. Furthermore, the two existing suggestions to avoid the use of unpredictable keys based upon data, while returning results as an object instead of an array seem somewhat contradictory except in the context of a predictably-keyed JSON envelope, so making this recommendation directly would promote consistency and clarity in our API standards.

If this makes sense, I, or one of my Testing Grouplet teammates, will be happy to draft a PR with suggested changes.

Generalize the URL recommendations

Right now, the URL recommendations are pretty specific and strict:

* A URL identifies a resource.
* URLs should include nouns, not verbs.
* Use plural nouns only for consistency (no singular nouns).
* Use HTTP verbs (GET, POST, PUT, DELETE) to operate on the collections and elements.
* You shouldn’t need to go deeper than resource/identifier/resource.
* Put the version number at the base of your URL, for example http://example.com/v1/path/to/resource.
* URL v. header:
    * If it changes the logic you write to handle the response, put it in the URL.
    * If it doesn’t change the logic for each response, like OAuth info, put it in the header.
* Specify optional fields in a comma separated list.
* Formats should be in the form of api/v2/resource/{id}.json

### Good URL examples
* List of magazines:
    * GET http://example.gov/api/v1/magazines.json
* Filtering is a query:
    * GET http://example.gov/api/v1/magazines.json?year=2011&sort=desc
    * GET http://example.gov/api/v1/magazines.json?topic=economy&year=2011
...

It's not that these are bad suggestions -- but there are lots of times when it's not necessary to exert this level of Fielding-ian rigor.

And every API is different! API URLs can and should adapt to make the simplest possible (and no simpler) interface for their function.

So I'd generalize this to a smaller set of core principles, in rough order of importance:

  1. Avoid single-endpoint APIs. Don't jam multiple operations into the same endpoint with the same HTTP verb.
  2. Prioritize simplicity. It should be easy to guess what an endpoint does by looking at the URL and HTTP verb, without needing to see a query string.
  3. Generally speaking, your API's URLs should advertise resources, and avoid verbs.

Request to change description to make it clearer for users

Hey!

I'm doing a quick audit of all of 18F's GitHub repos to make sure that descriptions, ReadMe's, and issues are written as concisely and descriptively as they can be. This will help other organizations who would like to adapt our code as well as the public — who may be interested in adapting our code or contributing to our repos.

The current title of this repo is: API Standards for 18F

Would it be possible to change it to: These are the API Standards for 18F and capture our view of API best practices and standards. We aim to incorporate as many of them as possible into our work.

That way, anyone who comes across it here or on GovCode will know exactly what the repo contains.

Thank you!

avoid using "entropy"

It tends to confuse. There's one thermodynamic definition that is frequently misapplied to different domains, and a distinct (though mathematically related) meaning in information theory, where it's measured in bits of uncertainty (but uncertainty within a problem space, not the kind of confusion referred to in these docs).

Actually, the second meaning comes about because of a related joke, made by John von Neumann when Claude Shannon was figuring out what to name it:

My greatest concern was what to call it. I thought of calling it ‘information’, but the word was overly used, so I decided to call it ‘uncertainty’. When I discussed it with John von Neumann, he had a better idea. Von Neumann told me, ‘You should call it entropy, for two reasons. In the first place your uncertainty function has been used in statistical mechanics under that name, so it already has a name. In the second place, and more important, nobody knows what entropy really is, so in a debate you will always have the advantage.

http://en.wikipedia.org/wiki/History_of_entropy#Information_theory

There's a related joke about engineers uniformly resorting to "entropy" as a name for phenomenon they don't want to fully describe. Anyway, I'm not sure it's the best fit here.

Singluar vs. Plural Nouns

First off, love the documentation and great work you have done throughout the Federal space on designing and implementing APIs.

I'm trying to follow your best practices, both encapsulated in this README and your API work in the wild but I'm having difficulty understanding your choice for using singular and plural nouns in the FEC Open API. Throughout the API you use /candidate, /candidates, etc.. and it is clear that /candidates is intended to return an array of objects while /candidate is intended to return one.

This practice is curious. As a Rails person I am used to plurals are all over the place in the API (even when intended to pull one record like the route /users/1). I was wondering if you could document in this README your reasoning for mixing singular and plurals.

under_score for JSON keys?

I see you recommend that people use JSON (yay), but also that they use JSON keys with underscores in them:

Use under_score case for keys. Different languages use different case conventions. JSON uses under_score, not camelCase.

Google's recommendation for JSON is to use camelCased keys. This is consistent with their naming of JavaScript identifiers, which allows you to use deserialized JSON as JavaScript objects:

person = JSON.parse('{"firstName": "Barack", "lastName": "Obama"}');
console.log person.firstName

Other tutorials recommend camelCase for JavaScript variables. Don't you think It seems a bit odd for api-standards to encourage people to use underscores in their JSON when it will make their consuming JavaScript code look inconsistent. It seems to give short shrift to JavaScript ... and JSON is the JavaScript Object Notation.

Why don't we just stay agnostic on this one? Or perhaps we should just recommend that an API's JSON is consistent with itself in the use of under_score or camelCase?

Document point-of-contact

No need to specify a solution, as this could be an email address, a link to an issue tracker, or something completely different. But a good API should allow its users to contact its producers.

"Don't use unpredictable keys" (in response JSON)

Perhaps we can suggest or link to some ways of dealing with this.

FBOpen has implemented some approaches to getting around this, since we house data from multiple sources, and it would be difficult, and even undesirable, for our purposes, to rename all of the fields. We initially implemented one approach, and for our Elasticsearch migration we are transitioning to another approach.

We've identified a core set of perhaps ten fields that we make sure are assigned a common name in our data. For instance, every solicitation has a title, close_dt and description, among a few others. However, each dataset comes with a bevy of other fields. Initially, we preserved the original field name but prefixed it with the data source id. for instance, if a field called FrooFrumFollies came from mydata.gov, we'd call the field mydata.gov_FrooFrumFollies. However, this ends up being quite verbose at times, and is also redundant with the data_source field (=mydata.gov) that every record contains, and may even cause issues with Elasticsearch's query parsing (via the embedded . implying a field hierarchy) so we've decided to throw all non-standard fields, with their original name, into an ext sub-object. So, standard fields are top-level to the object, while all others are located in 'ext'.

{
    "title": "My Solicitation",
    "description": "You want to work on this project. It will be awesome.",
    "close_dt": "7/1/2014",
    "data_source": "mydata.gov",
    "ext": {
        "FrooFrumFollies": "Scrumdiddlyumpcious",
        "Blagglepuffs": "1"
    }
}

Standard length of time provided for deprecation, changes?

How much notice should developers get before the API introduces changes? Breaking changes?

How much notice should developers get before an api or method is deprecated?

I have had govt APIs make breaking changes with zero notice and it's a big pain. I didn't see this covered in the document and I don't know what the standard length of time from notice to change should be but I think it merits discussion.

Replace JSONP with CORS

As recommended in WhiteHouse/api-standards#14, and by others, CORS is a far superior replacement for JSONP.

CORS is not supported on some older browsers, but unless XHR (Ajax) support in IE8 and below is a priority for the API, there are good reasons (complexity, security) to avoid adding it altogether. In other words, no JSONP without good reason, and CORS defaulting to on.

Justify use of charset parameter in JSON payloads

I noticed that the Use UTF-8 section claims that "An API that returns JSON should use":

Content-Type: application/json; charset=utf-8

It seems this came out of WhiteHouse/api-standards#22, but there wasn't much discussion on the topic.

While I fully support the idea of using UTF-8, it turns out that using charset parameters on JSON payloads is actually potentially problematic. The best explanation I've seen about this is a blog post from Armin Ronacher, the creator of Flask, who asserts that the JSON mime type intentionally does not specify a charset parameter, and that adding one introduces even more complexity into an already-complex situation.

Interestingly, some REST API tools side with Ronacher's interpretation of the spec, such as Django REST Framework, which actively makes it very difficult to actually include this charset parameter in a mime type.

This situation is complex, and I don't know what the solution is, but I do think that it at least merits some discussion, and the ultimate decision should be justified in some way. My personal solution has been to take advantage of the JSON specification's \u escape sequence and simply deliver all JSON content as ASCII, which avoids the debate altogether while still allowing unicode to be transmitted. But this can also increase payload sizes if they contain lots of non-ASCII characters.

for discussion: HTTPS everywhere

I don't expect to change @konklone's mind on this, but it remains true that there's a substantial performance penalty, some financial obligations, and various limitations on software flexibility imposed by requiring HTTPS. In many cases it is absolutely essential, of course. But for read-only APIs of public data where use bears no particular stigma, the case for it seems weak beyond promoting the ideology of the SSL-everywhere movement. Maybe I'm just still feeling burned by heartbleed, but I still don't see the payoff for most government APIs.

Offering it optionally is certainly desirable, though!

Advocating for SNI in government systems with its support where it currently seems to be strikes me as quite aggressive, but since this is listed as an optional item I think it amounts to an admirable display of technical leadership.

Stacktraces in production

Great document, all. One minor nit:

{
  "message": "Description of the error.",
  "exception": "[detailed stacktrace]"
}

Probably not the best idea to expose a stacktrace in production, right? Might want to clarify.

Remove recommendation to use a file extension to indicate format

I suggest we remove all use of the file extension (.json) to indicate the format of an API endpoint. This was fashionable for some time in the late 2000's -- especially for APIs that support multiple output formats -- but mime types in HTTP headers handle this far better. Plus, they communicate more information, like UTF-8 encoding.

Be a user of your own API

A strong recommendation that API producers should, if at all possible, have an in-house product that is itself a client of the API. "Dogfooding" may be a cliche, but it's an important grounding effect, and keeps the API design from veering off into theory and premature optimization.

Discuss the use cases you should consider

Three common ways people use (read-oriented) APIs, that you should consider from the client point-of-view when designing an API:

  • Getting everything. People may want to establish their own copy of your dataset in its entirety, rather than dynamically tying themselves to your API. For example, someone would like to build their own search engine on top of your dataset, using different parameters and technology than your API allows. If your API can't easily support this use case, you should provide a separate mechanism for acquiring bulk data.
  • Staying up to date. Especially for large datasets, people may want to keep "in sync" with your dataset without having to re-download everything. If this is a use case for your API, make sure this is easy to do in your API's design.
  • Driving expensive actions. (AKA the IFTTT test.) If your API syndicates records of events -- consider what would happen if someone wanted to fire off automatic text messages, or light up the side of a building, every time an event happens. Will your API's records always be published in a reliable order? Are they published in batches? Generally, consider the "entropy" an API client would experience.

Generalize the verb descriptions

Not everyone uses GET/POST/PUT/DELETE in the way the current standards lay it out. For example, the Twitter API uses only GET and POST, and the GitHub API throws PATCH in the mix.

The important principles are:

  • GET requests should always be non-destructive (no data should be affected).
  • Other non-GET HTTP verbs may be helpful in reusing endpoints in an intuitive, semantic way.

Removing support for multiple formats

I suggest we remove the recommendation to support multiple formats.

Supporting multiple output formats adds complexity to an API, and the benefits are not clear. As long as the API is producing information in a well-supported, machine-readable format, clients can be expected to write or use libraries that process it.

The added complexity is because it is non-trivial to "export" data to different formats without data-specific post-processing. Some examples:

  • Many formats use different case conventions: XML uses tag names like last-name, JSON uses field names like last_name.
  • Some formats allow different syntax. XML forbids the use of spaces in tag names, while JSON allows them.
  • Formats have varying levels of richness. XML allows tags and attributes -- JSON has no attribute equivalent. So, often, XML output in APIs doesn't use attributes, in order to support easy export to both formats. Similarly, it discourages use of spaces in JSON fields if XML is going to be supported. This pushes APIs to use the lowest common denominator of data representation, instead of taking full advantage of any given format.
  • Not all formats can represent the same kind of data -- adding a CSV format, for example, means jamming hierarchical data into a tabular shape.

Finally, multi-format zeal in Rails-world led to a security bug -- ActiveRecord's automatic parsing of various POSTed formats included YAML, and Ruby's YAML parser had a very bad security flaw.

Better to just pick a format, and stick with it. That's what most of the big APIs are doing these days, and it makes just as much sense for small APIs as big ones.

Slightly generalize pagination

Encouraging pagination, and the inclusion of pagination metadata, is a good idea (where there are results to be paginated). The specific syntax and metadata schema used to accomplish that matters less.

expand acceptable input param vehicles to include full URIs

No reason to restrict folks to the querystring -- plenty of systems out there that rewrite URLs and they work just fine. I could understand going querystring-only to enforce a single pattern, but if you're going to do that I'd suggest striking the header option, which many people find to be a pain, if only because it's harder to document a call for debugging or discussion if you need to pay attention to headers.

Removing version numbers

I suggest that version numbers be removed as a standard.

For one, including them in the URL is a clunky way of handling versioning. GitHub's API handles them as HTTP Headers, which I think is a more sane way of handling it: it allows your version strings to be longer and descriptive than one would be comfortable with in a URL, and lets the URL stick to describing where you're at and what you're asking for.

But more than that, I think versioning an API at all is premature optimization for any API that isn't setting out to be like, a 10-year evolving flagship service. If an API is going through a major version change, it's easier in a lot of ways to just set up shop at a new domain, or new path. For a major (as in, backwards-incompatible) new version, clients are going to have to update their code/libraries anyway -- version numbers don't add any value on top of domain names, for all but the most advanced use cases.

Committing to handling a version number, in either the URL (as a path param or a query string param) or in HTTP headers, means you're committing to make each version of the API smart about processing a version number, in some blunt or sophisticated way. That's extra complexity, and usually it's not needed.

Standards for API documentation

I'm not inclined to recommend specific "solutions" for API documentation. Tools like Swagger, Apiary, and Iodocs all provide helpful accompaniments, but all are not great at being the sole documentation for an API.

Instead, I'd like to emphasize the goals that API documentation should have, and link to examples of other APIs embodying good practices of different kinds.

Goals of good API documentation:

  • High-level "This is what the API is, what you can do with it, how our URLs/responses are designed" introduction.
  • A quick-start or "hello world" tutorial.
  • Real, syntax-highlighted example responses, next to the URLs that generated them.
  • The documentation can be improved by users, e.g. is itself versioned in GitHub.
  • Explanations of each field, and what promises that field is making. (e.g. possible enumerated values, whether it can be null, what type of data, an example value).
  • Are clearly written, in professional language, without typos and grammatical errors.

Not all of these are deal-breakers — and clarity is ultimately a higher priority than 100.0% precision — but all contribute to solid documentation.

Hypermedia APIs

I don't know a lot about them! And I've never done one, so I'm not working them into the rewrite branch. But they are growing in popularity, most notably in the GitHub API. So this could be a good discussion thread for people with experience/opinions about them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.