Don't forget to offer PLENTY of immediately usable examples of the API. Like Pivotaltracker has copy/paste-able curl commands to try out the API. Have libs with consistent examples for all popular (and, if for some free PR, less popular languages). Version your API in the URL; you might need large changes to existing stuff, so you cannot trust on backward compatibility all the time while it is really annoying for devs when something works if they have to change it (or it stops working).
Edit; hire 'average' programmers from oDesk etc to build 'stuff' against it 'for clients' (threat it as a serious project) to figure out how easy it REALLY is to make things with it. Average programmers are, well, the average, so they will be the most likely consumers of your API. If they have no clue at all, you didn't go far enough perfecting everything. For instance we hired a bunch of devs to do a Windows plugin for our monitoring system and we found out our documentation and examples were completely unusable for them. We'll have to rewrite/refactor all of that and have them re-try.
You said it. I have this feeling people tend to forget developers are users too. The "don't make me think" rule still applies even if their job is thinking.
So if you really want people to use your system (API, library, IDE, programming language, compiler...) you should run usability tests, write easy-to follow documentation with examples and answers to common problems, make it super easy to download (if it's software), maybe make a web page where you can try it online (that helps a lot), have a nice, smooth user interface, make it behave similar to something users have probably already used, have a good name, a nice logo, a nice-looking webpage, take care of its search-engine positioning, offer services such as forums, maybe advertise a bit, sell shirts, give a free night at a spa to one of the users every month (hey why not)... wow that list came longer than expected. Well you get the point.
This article is bad advice for 99% of startups. It says "your API might become heavily used, so engineer for it up front".
I have an alternative suggestion: "Your API (even more so than your product) is most likely never going to be used by anyone, so engineer to get it out the door as quickly as possible and test the waters."
Authorization, throttling, quotas, and monetization are all things you can worry about in the happy-but-unlikely case that your API takes off. In the mean time, just get it out the door. There are some things you can do to future-proof yourself with zero effort:
* Require every request to submit a contact email address as a parameter. This gives you a crude way to find out who is using your API and how much, and gives you the ability to contact them when you make breaking changes. Clients who don't submit contact information have nobody to blame but themselves when you make breaking changes.
* Put your API on a different domain from your main site, ie api.example.com instead of www.example.com. This gives you more flexibility to move it around without breaking things.
* Documentation is critical, but easy - provide examples. Just a series of "Want to do X? Formulate a link like this" and make a real link that actually works.
* Don't overthink the API. Yeah, use REST principles and don't be a total idiot. But accept that your first API is just an experiment. If your API is successful, you will end up rewriting it. The most important things are that 1) it works, 2) it's useful, and 3) users can figure out how to use it from the documentation. Just get something out there, even if it isn't pretty. If you need to make breaking changes, that's what the contact email is for.
We (https://www.voo.st/) added an API in response to a partner who asked for it. It took a day, half of which was formatting the documentation (https://www.voo.st/developers). Guess what? It's never been used. Chances are, your API will be the same way.
I'm not convinced that versioning media-types is the best way. I agree it is a more correct way as opposed to basically abusing REST, but I think overall putting the version in the URL is better.
From the linked answer:
> * you break permalinks
> * The url changes will spread like a disease through your interface. What do you do with representations that have not changed but point to the representation that has? If you change the url, you break old clients. If you leave the url, your new clients may not work.
Putting the version somewhere else in the request doesn't fix this. If you drop support for an old API version it is going to break stuff. It is easier to spot the issue if you return a 404 rather than a 500 or 400 error, or even correct data that breaks the app consuming the API as it is expecting something else.
> * Versioning media types is a much more flexible solution.
The main issue I have with this is I have had the "pleasure" of working with pretty stupid people implementing clients on my API. They easily get POST and GET requests mixed up, HTTP and HTTPS, whether or not the request should be authenticated. I don't want to add something else to confuse them even more...
> The main issue I have with this is I have had the "pleasure" of working with pretty stupid people implementing clients on my API. They easily get POST and GET requests mixed up, HTTP and HTTPS, whether or not the request should be authenticated. I don't want to add something else to confuse them even more...
So you are willing to do the work of those other devs for them, and cripple your own API in the process?
If he wants to expand his user base, yes he is. The essence of a business is doing other people's work for them and then charging them. If doing other people's work for them also brings you money, well, you'd better have a very good reason not to.
> The main issue I have with this is I have had the "pleasure" of working with pretty stupid people implementing clients on my API. They easily get POST and GET requests mixed up, HTTP and HTTPS, whether or not the request should be authenticated. I don't want to add something else to confuse them even more...
Where does the madness end? Do you treat everything as though it were GET and stick the real method (and every other request header) in a query parameter? I think it's ok to assume a basic level of understanding of one of the best documented specs in computing.
What's your definition of "basic level of understanding"?
A public API is about 99% of what we (Crocodoc) offer. While designing the latest version of our API, I always erred on the side of staying true to REST principles. Fortunately there were others on our team that erred on the other side. The result is a happy medium that certainly veers from the canonical definition of REST but is arguably easier for Joe Developer to play with. Guess what...we still receive an incredible amount of support requests from developers getting stuck.
It's tempting (and fun) to build APIs "the right way" and use little tricks like putting versioning in the media type. However, that's pretty often at odds with product/user experience/business considerations. Why offer a product that only 10% or 20% of your customers are savvy enough to use?
Each to their own I guess. However personally I would rather not spend time tracking down a "bug" due to a client not consuming my API as documented. If I can make it easier for them to use, by not doing things the "correct" way, then I would rather do that.
Using a content-type header instead of .json or .xml (etc) extension in the URL is just another example of this phenomenon. There's a reason people are moving to use dot extensions in URLs - it's easier to adopt and test.
While in theory great Accepts are just additional burden for web developers. We don't want to need to deal with headers. We want to fetch an url and get _the_same_data_ no matter if the url was entered in the browser, wget, or inside the app we're writing.
For a simple developer, output format is just another parameter and it shouldn't be hidden in HTTP stack.
I don't think 1 additional line of code is much of a burden. If you put it in the URL you're forcing the server to ignore the Accept header that the browser sends and pay attention to some non-standard url substring instead.
I was fooling around with Javascript MVC lately, and came across a problem -- let's say I have this URL, "example.com/objects/1". If I open it in the browser, the server returns a barebones HTML page. JS in the page makes a separate ajax call to the same address, the server detects the accept header, returns JSON data, and the page is populated with content.
Now I navigate off the page to a different site, and press the back button. Instead of the HTML page, I get the cached JSON response. Now if I change the ajax call to "example.com/objects/1.json" instead, that keeps the URLs separate and the browser won't cache the wrong response. Is there a better way to solve this?
The problem I have with Vary headers is that many reverse proxies will just not cache anything with a Vary header. The reason is that if they add the value of the header that "varies" to the key of the cache, now they have to cache under many different keys the same content.
Think of all the different "Accept" headers that clients can send you, each one of these will get an entry in your cache. And now add other headers that should also be in "Vary" like "Cookies", "Accept-Language", etc. and your cache will be virtually useless.
Interesting. Perhaps, instead of relying on "Vary: Accept" the server should respond with: "Vary: YourCustomHeader". The API client, on the other hand, will include "YourCustomHeader: SomeConstantValue" when making requests to the server. That way, the reverse proxy will only store up to two versions in its cache.
It's not just one additional line of code. It is additional work every time you try to view result in the browser. Which you basically can't because you can't put accept header in url bar..
At least in python, making requests becomes quite a few more lines of code if you want to add headers. There's usually a short-hand command if you just want to get full data from an url and a "create-an-object, then set these parameters, then this, then open a connection then read what's there".
Mandatory headers are just a way to make life of a regular developer painful.
Sounds like you just need to abstract that part into a function. Much better solution than breaking HTTP. HTTP is not supposed to send the same results for a given URL, it is supposed to send the same results for the a given request. In the case of the browser, it asks for HTML.
I can see that using "Accept" can be considered a more elegant solution, I don't see how adding a parameter will break HTTP. There is nothing in the HTTP standard that says what an URL should or should not return. The Accept-header is just an additional source of information.
Not actually, the Accept header isn't a mere suggestion. If the server chooses not to fulfill it, the correct response is 406 Not Acceptable. This is why browsers send something like this in their Accept header:
This is exactly the reason why even the good standards fail. Instead of writing 10 lines of code to abstract your specific use case, you want it to be the default behavior. How many times have you cursed something like IE for not implementing CSS properly?
I run a free service (http://eve-central.com - I am not a designer ;)) which has an open API - no rate limits, no accounts, no signups, etc. Yes, technically this is bad, and has had interesting implications for support (some APIs date back to 2007 without any changes), but in this case is the right choice. It works by throwing enough power behind it, and relying on caches. The API is popular for its audience - approximately 50+ million calls per month, which easily outnumbers the (ad supported) web front end pageviews.
Due to licensing of content, it would be iffy to monetize directly (technically even the ads are in violation of that), so I don't even consider it.
Very cool :). If it doesn't make sense to monetize it might still at some point make sense to put sanity limits on some usage - otherwise some high volume users could end up making you take it down for cost reasons.
Great service. I used it a few years ago when I was still playing Eve. One thing I had been hoping would be added for a long time was json formatting in addition to XML. Have you ever been able to add this is in?
The best API design I have come across so far is from Zencoder [1]. Their documentation is spot on and they also have a nice little API builder. I found it interesting to study while doing designs for our own API.
Interesting article. I wasn't aware of services like 3scale. Anyone got any experience of using them?
I developed, and am responsible for, a moderately complex b2b web API that is been in use for about three years. A b2b API embodies a contract between organisations, and it's important to understand that this is different to b2c (e.g. Twitter) which is less restrictive.
The biggest issue for me has been dealing with change. User requirements change. The underlying system changes and accretes new features that need to be exposed in the API. How to deal with this without either compromising the integrity of the API's design or (at the other extreme) breaking systems that use the API, is not easy. I don't know of any easy answers, but design your URLs and data schemas with versioning in mind and get to know the developers who use your API.
Documentation is very important. If your API exposes complex data then make sure that you have good documentation on what every data element means.
I'm from 3scale - so factor in any bias filters!) - we definitely think of it as a contract between the provider and user of the API - could be very lightweight or heavyweight - but basically it's a bunch of rights on the API v's a promise of good behavior.
Actually a lot of the APIs that use us are B2B because you often have different tiers of access rights and limits + want to have approval steps etc. for sign-ups. These are pain to code yourself.
The change part is a big deal - we normally deal with it in two ways: 1) launching parallel services for major versions so people consciously migrate their apps, 2) incremental updates - docs are versioned but all the same calls work on the same endpoint. How the version is flagged in the call is rather independent (URL, header, type).
We also use the swagger docs framework (http://swagger.wordnik.com) to create interactive docs to try keep questions on the API itself to a minimum (people can play with it themselves).
"The best way to do that is offering it up as a service – a RESTful API even."
I must admit to being a big fan of RESTful APIs, but I'm skeptical of treating any technical approach as being universally applicable. Are there any likely scenarios where a RESTful API for a web service is not going to be a good idea?
Sure, the original thesis (by Roy Fielding) mentions some disadvantages of the constraints that are the basis of REST:
Stateless:
The disadvantage is that it may decrease network performance by increasing
the repetitive data (per-interaction overhead) sent in a series of requests,
since that data cannot be left on the server in a shared context. In addition,
placing the application state on the client-side reduces the server's
control over consistent application behavior, since the application becomes
dependent on the correct implementation of semantics across multiple
client versions.
Cache:
The trade-off, however, is that a cache can decrease reliability if stale
data within the cache differs significantly from the data that would
have been obtained had the request been sent directly to the server.
Uniform Interface:
The trade-off, though, is that a uniform interface degrades efficiency,
since information is transferred in a standardized form rather than one which
is specific to an application's needs. The REST interface is designed
to be efficient for large-grain hypermedia data transfer, optimizing
for the common case of the Web, but resulting in an interface that is not
optimal for other forms of architectural interaction.
Layered System:
The primary disadvantage of layered systems is that they add overhead
and latency to the processing of data, reducing user-perceived performance.
I fully recommend reading the thesis instead of relying on the vox populi that often times misrepresents what these concepts really mean and what advantages they bring to the architecture of the system: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...
Definitely. REST(ful) APIs are good approach for where you have clearly identifialble resources, which is what they are all about. But if your API is more procedurally oriented -- take as a clear example a simple Web search -- than REST is not the most optimal approach.
There are plenty of situations where most of RESTful idea has no meaning.
Zemanta's API is one of them. We're not dealing with resources, we're dealing with analysis of text (natural language processing, information retrieval, etc...), so except of the basic url scheme, there's not much that you can take from the RESTful idea.
Dealing with resources is just a point of view. Reading the documentation, it seems very easy to model it in a resource-oriented way; in fact, what they call "objects" (articles, keywords, etc) are essentially resources, which are created from the original resource (the text you submit).
You could just POST the text, get back a bunch of links to the resources and then GET the ones you're interested in.
Assuming that certain "objects" are more expensive than others to generate, a resource-based view with lazily-generated representations could be more efficient than wasting resources without knowing if the client needs them or not.
They are not created in any persistent way. They are entirely ephemeral to that specific request.
What's expensive is the analysis of the original text, not creation of the objects. If you want to do what you are saying you would need to create and store objects server side in order not to have to re-do the analysis the second time around. There's no point in that.
When you're offering to large old-ish enterprises like banks and such you will likely want to go with SOAP.
When you have a lot of high-speed data, you will want to go with sockets and a live stream of small bits of data. Like Twitter's firehose for instance, or getting Wall Street data for your bot trader.
First you use SOAP and it's nice, but after a while it's not good enough and you implement WSDL. Corporate overlords see it and suddenly everything has to be WS-YouNameIt (especially in banks and big telco). You end up in the deepest valleys of XML hell, colloquially known as WS-DeathStar.
You can have both, and you can do it in a consistent way. Not that you can make everybody happy, but it's close enough.
For example we implemented our API with both XML-RPC and REST + JSON interfaces (http://www.memset.com/apidocs/intro.html). All the methods are available and work the same way in both interfaces. There's some extra work to deal with some of the types (ie. dates in JSON), but it's not too difficult.
So we have one implementation/docs, but two interfaces to access to it.
Actually, the difference between XMP-RPC and REST is not just in the format of the response, the difference is the whole approach. The way you have described (didn't go into the docs) you don't have REST at all, just XML-RPC that returns JSON. Sorry if I misunderstood.
There are two different interfaces for the same implementation. Let me stress the different part. The RESTful API uses JSON to encode the responses, but that's all.
Sorry if I didn't explain it very well, the docs are clearer though.
The point is that your RESTful API is not RESTful at all. It's just RPC using JSON. REST is an architectural style that models the interaction around data and hypertext instead of actions.
A good rule of thumb is: if the documentation mentions "methods" as anything other than the uniform ones (if you're using HTTP, that would be GET, POST, etc), then it's RPC, not REST.
Note: I'm not saying your API is bad; RPC is a completely valid model. I'm just saying it's not RESTful.
You're not supposed to have session state - but the resources you are accessing are (of course) stateful. Why not set up your subscriptions explicitly as resources that can be manipulated through the API?
I think versioning API is an illusion.
It is all source of complexity that eventually kills us.
Give up keeping exactly the same behavior as actual models change.
Edit; hire 'average' programmers from oDesk etc to build 'stuff' against it 'for clients' (threat it as a serious project) to figure out how easy it REALLY is to make things with it. Average programmers are, well, the average, so they will be the most likely consumers of your API. If they have no clue at all, you didn't go far enough perfecting everything. For instance we hired a bunch of devs to do a Windows plugin for our monitoring system and we found out our documentation and examples were completely unusable for them. We'll have to rewrite/refactor all of that and have them re-try.