The Many Ways in Which the Yammer API Sucks
A lot of the guys out in our San José office have been using Yammer recently. For the uninitiated, Yammer is a lot like Twitter, but with access controls, making it more suitable for communication within a company.
Yammer exposes an API for developers to hook into, so I thought it would make for a fun Sunday afternoon project to see if I could put together an Opera Panel interface, which - if done right - might double as a mobile Web interface. Unfortunately the Yammer API is awful, so awful that it's basically futile to try to work with it. Here are some of the ways in which the Yammer API sucks.
It uses REST, and Badly
Unfortunately, REST has become something of a buzzword. It's how all the cool kids are building their APIs these days.
Except that it isn't: Yammer's so-called "REST" API is so far removed from the REST architectural style that it is misleading to name it REST. This is a common mistake made by API designers, and is understandably a sore point for the creator of REST, Roy Fielding.
But my grievance with Yammer's pseudo-REST API isn't purely academic: it's the fact that it is a complete pain to work with. This is simply because they've gone with the flock, eschewing something sane, such as SOAP, so they could claim to be using this cool new REST thing.
Bear in mind that even real REST services are - in practice - virtually impossible to describe formally. This in turn makes it impossible to programmatically consume them. Instead, the end-user (me) has to read through pages of informal documentation, manually code the API calls, piece together URLs, and write code which is closely coupled to the mechanics of the API.
By contrast, look at SOAP and its description mechanism, WSDL. Because a SOAP service can be described formally using WSDL, it is trivial to consume a SOAP service with minimal human intervention.
I'll use PHP by way of an example, since it's what I know, but the principle will be the same in any language. Here is an example of how to consume a "Hello World" type SOAP service in PHP. Note that this SOAP support is not even at a framework level, this is built into the language itself:
<?php
$service = new SoapClient('http://example.com/soap.wsdl');
$response = $service->sayHello();
That's all there is to it. This ease of use is fundamentally not possible with REST, and even less so with the Yammer API. A developer who wants to work with the Yammer API must, as mentioned above, trawl through docs and manually program each and every call they want to make. This truly sucks, and it certainly makes me not want to use the API.
It uses OAuth
I'm sure that OAuth probably has its place, but using it in what should be a simple API is a major WTF. Implementing OAuth is about ten times more complicated than implementing a client for the Yammer API itself (even with it being a retarded REST service, see above), so this really is the tail wagging the dog.
Improved framework-level support for OAuth will no doubt happen at some point, but even so, how is forcing me to jump through the OAuth hoops better than letting me append the authorisation credentials as parameters to each call? Or using HTTP authentication? Wouldn't that be significantly more RESTful? Is it a matter of trust? If you don't trust your application developers, you probably shouldn't be exposing an API in the first place.
It's Broken
In order to work with the Yammer API, the first thing an application developer needs to do is to register his or her app.
It turns out that if I register, say, "yammer.example.com" as my app's address or callback URL, Yammer happily accepts it, but isn't smart enough to figure out that it needs to add "http://" to the hostname before redirecting a user to it, so any links or redirects from the Yammer site to my app (necessitated by the decision to use OAuth, see above) are broken. Thus leaving my app fundamentally broken.
Furthermore, there is no way whatsoever to edit the details of an app once registered, so this problem is terminal.
It's Dumb
Since you have to register your app's various URLs up front, there's no way to dynamically send other (e.g. callback) URLs to the service, so it's basically impossible to implement a development version of your app. This is also terminal.
It's Really Dumb
I'd like my app to work within a small amount of screen space. As I mentioned, I'm primarily thinking of developing an Opera Panel, but I hope that if I get that right, it should actually work rather nicely as a mobile Web interface to Yammer anyway. So, when it comes to interacting with the Yammer site itself (which I have to do since they insist on using OAuth, see above), I'd like my users to see the mobile version of Yammer.
Now, to toggle the mobile view, the user must simply click on "Switch to mobile version". If you're currently in mobile view, that page switches you to normal view and vice versa, presumably by dropping a cookie. Effortless, right? Wrong. This makes it impossible for an app developer (me) to provide a straightforward link to the mobile version of Yammer! At least, not without knowing what view the user is currently in, which I cannot possibly know.
Furthermore, what happens if you happen to be in mobile view, and are happy with that, but accidentally hit the "toggle mobile" link? Yep, you're bumped out of mobile view, and good luck with getting back.
Conclusions
So I, and presumably others, have been forced to give up on developing a Yammer app for the foreseeable future. I'm aware that the Yammer API is in Perpetual Beta™ (that's how you know it's cool, right?), and so some creases will be ironed out. However, given that many of the issues are the result of architectural decisions rather than bugs, I won't hold my breath waiting for a usable Yammer API.
Simon Harris
Ciaran - unusually, we appear to agree on a lot of this. However, I'll take issue on this point:
"a formal spec of the available methods shouldn't be required because...[RFC 2616]"
I don't think that this gets REST off the hook. I love HTTP to bits (I owe my career to it) but the HTTP RFCs do not tell me anything useful about how to consume your REST service; if I want to work with your API, I still need to trawl through that informal Word/Wiki/Web document you mention, and then manually code each of the calls myself. And I'm fairly busy these days, y'know?
Admittedly, I don't know what you mean - in this context - when you say "what the various content types involved are", or how that would help. Can you explain a bit more?
Ciaran McNulty
Well, the available actions are GET
, POST
, PUT
, DELETE
and so forth, which are defined in HTTP. If you aren't allowed to do one of them then there's a response code that lets you know that, so there's not much more documentation needed.
For example, what I'd consider a "bad" REST service would be one that said something like "To find a user's details do a GET
to /user/<userid>", because that's the sort of informally documented stuff you're worried about.
A better service might say that the /user resource represented a list of the users, so that the developer could request a representation of that. The documentation would then revolve around defining the types used in the data transfer, e.g. in this example maybe an XML format for listing the URLs of the user resources. You don't then need to say "you can GET
these URLs" because, well, they're URLs.
I'm interested in your idea of some sort of formal service definitions for REST services, but don't quite know how that would work?
Cristian Vrabie
I cannot agree with your statements regarding OAuth. You basically say that we should throw security for coding simplicity which I think is deeply wrong. Yammer is corporate oriented so security is a priority. The credential auth you're suggesting is flawed and easy to crack -> OAuth. Is not even that difficult if you use (or build) a small framework.
I think you were in a lazy Monday morning when you wrote this :)
Simon Harris
No, Cristian, I did not say that. My gripe was with the sheer impossibility of building a working user interface on top of the Yammer API, let alone a mobile one.
Nearly two years on from my post, no one has managed it and Yammer is essentially dead. I hate to say I told them so but, well, I did.
Tommy Kelly
> Yammer is essentially dead.
How so?
Simon Harris
Tommy -
Dead in the sense that nobody uses it. Do you? Granted they still have a website, but there's no sign that they have a future.
Toby Beresford
I've used Oauth2 with Yammer which is pretty easy.
Daisukeman
I really liked your article (and it made be laugh, a lot!)..
But I do sense somewhere in between of your bad experience with the Yammer API you start to name all issues related with REST services.
So according to this, does Google, Facebook, Twitter, etc REST services using oAuth suck as well?
If not, how is this different?
Bob
I searched Google for Yammer API and yours was the second hit. Congratulations. So, five years later, opinion still the same? Yammer still around so I guess they didn't die. Have they improved? I'm comparing Jive, Yammer, "roll my own", etc. and curious what your thoughts are now.
Ciaran McNulty
In a well-done REST service the "spec" should just be about what the various content types involved are - a formal spec of the available methods shouldn't be required because, well, it's here and in later RFCs:
http://tools.ietf.org/html/rfc2616
I think where HTTP services go wrong is that they try to get the client to build URLs based on a scheme that's informally defined in some document, which I think is antithetical to RESTfulness - URLs should really be opaque to the consuming app.
SOAP is very easy to use in comparison, from the developer point of view, but like all things it's a trade-off. SOAP includes a lot of transfer overhead but integrates well with an OOP style while REST is very efficient at the HTTP level.
For instance it has a very rich caching semantic that's widely implemented - the fact you can buy a bit of hardware, or install some standardised software to sit between your service and the web and provide caching is pretty useful.
On another subject, OAuth is a mess but is a good solution to "I want this application to be able to use this service, but I don't trust it enough to give it my login". For that one win you get a whole world of pain in trying to implement the bloody thing, but I've not seen a better solution to that problem.
Hopefully, like OpenID, it'll get bundled over time into libraries that take that pain away. It'd certainly be useful for services like Yammer to offer "direct" login as well as OAuth.