Tesla Model S JSON API
docs.timdorr.apiary.io
docs.timdorr.apiary.io
It's like XML all over again. Should it be an attribute or a child node? Should the parameter go in the header, or in the body, or in the URL? Should it be part of the URL path, or a URL parameter? Should the error be indicated in the HTTP status code or just in the body? Did we get it right, or do we need to find a Roy Fielding quotation illustrating the principle we violated?
Normally this wouldn't bother me, since I generally have faith that the "free market", so-to-speak, will favor the best technologies in the long run. But HTTP and REST have an artificial boost in that they are the only way to get through many firewalls, so in essence everyone has to go along with REST whether they want to or not (or at least tunnel over it). And of course everything can be made to work with REST, so everyone eventually converges on it, even if it's not the best fit, and its dominance grows.
</sarcasm>
To reply to my siblings:
HTTP is in practice a great transport protocol, because of the world we live in. That's an affront to ivory tower engineering (my favorite kind), but it's a lot better than failure to ship (or shipping something that only works under non-existent conditions).
And RPC needs some kind of container protocol, and SOAP is one possibility, sure. Keep it the hell away from ME, but it's one option. The sane option is to do just what all these so-called RESTful services actually do (modulo not using GET when you should POST), with pleasant-but-not-dogmatic URIs, and JSON, and so forth, and just stop calling it REST, because it's not REST at all. Or call it whatever you like, but get used to endless trolling from pedants like me.
Aside from the bad HTTP verb choice, isn't TFA a pretty reasonable API implementation?
Of course, as sillysaurus noted.... TFA doesn't call it RESTful at all... that was just the HN headline. Oh how we've been trolled.
Perhaps, just as JSON became a more functional and popular format than XML we can build a new REST spec that simplifies all this.
http://stackoverflow.com/questions/24482179/whats-the-best-a...
The main problem is that it's not just a small deviation from REST, but the absolute opposite of it. That's hard to ignore.
To most people, honking the car's horn is an unwanted side effect.
As has already been pointed out, some browsers will fetch-ahead to ensure that pages appear to load instantly. If you open a page which is a bunch of buttons which do stuff like honk the horn, lock the door, raise the window or open the charging port door, there will be unwanted side effects.
So yes, we do care that much.
1. what happens if you visit a control panel page in chrome? Does chrome spider ahead, eagerly caching the links on the page assuming that visiting a page has no side effects? Have fun silencing your horn and windshield wipers from simply visiting your control page.
2. what happens if chrome then has that "get" url very strongly cached? After spending 10 minutes trying to silence your car from your first visit to the page, the "honk horn" button now does nothing but load the word "true" from the browser cache.
3. what if any of the above happens while you are on the road ? what if some wise guy down the line decides that a car should be designed API first, and your dashboard, pedals and wheel are just one of many potential API clients? Can you really now tolerate using the GET method in ways that it is explicitly documented to not be used?
This isn't just philosophical or quibbling over definitions. Getting this wrong means things actually break in the real world.
I agree that if anything between you and the server is going to cache requests then you need well-specified behavior around that. But that particular problem can be solved by a specification much, much simpler than all of HTTP.
I also see that it's useful to know that certain requests will not be state-changing for purposes of pre-fetch. But while I agree this is important for the browser, I question how important it is for APIs. API calls are usually constructed programmatically -- V8 isn't going to start just randomly guessing what XMLHTTPRequests you might come up with next and start fetching them. This is where I think that browser-based paradigms with a human user diverge from programmatic ones.
I get what you're saying about the API… but if you're going over HTTP why not play by HTTPs rules. Presumably it's an app that is the primary consumer of the API so they could use any sort of protocol. Why decide to use HTTP but not conform to the standard in a way that ruins any benefit you might have got out of using HTTP instead of say:: OSC or.. basically anything OTHER than http would be better.
If we're talking about using HTTP to bust through a firewall, then that stuff is DEFINITELY going to break unless you use HTTP in as dull and ordinary a way as possible, and GET requests will always be cached by god knows how many different machines between you and the car.
If it's not an app, then we've decided to put a webserver on the car so that we can serve a website with some javascript that does XHR calls to make things happen. I would not put it past google to make a future version of chrome that prefetches JSON api requests. But regardless, yes, XHR calls do go via the browser cache. and the proxy cache. and the firewall. and any other machine that makes basic assumptions about what those methods mean.
Sorry if I was unclear -- I wasn't advocating a mis-designed API, I am suggesting that HTTP is way more complicated and subtle than it needs to be for the purposes of remote APIs.
I concede that providing enough information to know what is cacheable (and what the caching key is, etc) is justified complexity. But I think that the other 95% of semantics that "pure" REST demands you follow are pretty useless and pedantic.
I too am not very fond of REST, but for slightly different reasons. While I acknowledge its benefits, I'm afraid REST will go the way of OOP in terms of fad-chasing, resulting in massively over-architected and contrived systems.
Very few concepts have been so hugely corrupted to mean exactly the opposite of what they mean as REST. This is probably the least REST API in existence.
This would make sense if you wanted to GET /honks and see a collection of previous honks. (Modifying an existing honk doesn't make sense, so we wouldn't have to worry about it.)
As far as I can tell, REST is appropriate in very few cases.... although it IS appropriate for more cases than it might first appear.
[1] Except that it really ought to use POST.
I'm not usually in favor of nested API design, but complex resources like cars make sense, so:
PATCH /vehicles/{id}/horn { "enabled": true, "timeRemaining": 1000 }
You could do it as a PUT or PATCH, but you'd have to do it differently from in your example in order to preserve idempotence, due to the complications of working with time.
Remember, if the request successfully goes through twice that should have the same effect as if only the first succeeded. One way to accomplish that would be to give an absolute start and end time for honk to be on. e.g.,
PUT /vehicles/{id}/horn { "enabled": true, "time_start": "2014-04-12T20:12:36.1", "time_end": "2014-04-12T20:12:36.6"}
for a half-second honk.
If the resources of the car were mapped and had states it could work fine with a full REST interface. You could change the state of the horn like you change the state of a switch. You'd change the horn to be "on", not call some "turn it on" procedure.
They have some indications of that. There's a URL that returns the state of the vehicle (driving and position). That's something that could be mapped as a first-class citizen and someone could mess with it with the semantics of the verbs.
Commands are a much more RPC area though, REST doesn't map perfectly. You can almost always make a command into something of a resource state change, it just isn't always simpler. REST wouldn't give them much in this case as it's hard to imagine they'd make use of any of REST advantages. Not that there wouldn't be any technically (being able to evolve APIs without breaking clients is a pretty big advantage, plus plenty of other things), but that for their business it doesn't matter (they control every client).
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...
After reading this I cringe whenever I see any API claiming to be "REST(ful)".
I don't even know how I'd write a client against a server that arbitrarily changes endpoint URIs. I honestly don't see a benefit of RESTful if REST requires complete decoupling of the server and client. REST isn't SOA. There is no discovery API for REST. If I don't get to hardcode /api/vehicle/, then how else can I write a functional client?
If you follow a link you don't care what the URL is. You never needed to type out "/reply" to use Hacker News, you don't need to do it to use an API. That's what the article is about.
The actual URL is unimportant, you just need to know what the link for "/api/vehicle" returns to do something useful with it. Like you knew that "/reply" would give you a form with a place to type out a reply.
> I don't even know how I'd write a client against a server that arbitrarily changes endpoint URIs.
The thing is, you don't have to. I can write one for you and you'll never need to write another one again. You could use it and just have to implement the part that matters to your application, the semantic of it. You wouldn't need to hardcode anything, or even handle URIs at all.
You could use it for Tesla's API, Twitter's, Facebook's, whatever. If they used links you could use the exact same client for anyone, just needing to re-write the logic part (like creating a post on Facebook, a tweet on Twitter, etc).
Problem is hardly anyone actually implements links so you can't do that. It sounds like utopia but it's just the product of extreme decoupling. It's not really any different than browsers.
Best places to be are at discussion groups (api-craft, rest-discuss). Steve Klabnik has a good book on REST that explains it in more layman's term. Fielding's a PhD (REST was his thesis) so his writing is intended for an academic audience, it's indeed hard to follow without previous introduction.
I actually "understood" it on api-craft. The real-life examples it has are very helpful.
My fault for calling it that. It's REST-ish, but not RESTful. Tesla never called it that (they don't even officially acknowledge the API), so it shouldn't be misconstrued as them not knowing what REST is. This is their internal API for the mobile apps, so they're free to design it however they like.
Of course, if the API is going to be growing, you may want to organize it in a guessable format...also, if it's going to be growing, I wouldn't mind helping/testing. :D
This is the first time I've seen URL APIs not being referred to as RESTful. What makes it non-RESTful?
Fielding's REST says absolutely nothing about URLs or their structure.
Everyone else's REST (and, the HTTP spec) says that you shouldn't use GET to cause a side effect.
I've never liked the dogmatic aspect of REST anyway, saying that API's should only ever be REST-ful is like saying that you should never call functions in your programs and only ever use getters and setters.
Still, I'm gonna bet that someone's gonna find a way to abuse this in a hillarious way.
PUT /vehicles/{id}/horn
{
"command": "honk"
}The main problem with using PUT is that PUT is supposed to be idempotent; the result of two PUTs with the same content should be the same as the result of a single PUT with that content. But two PUTs to honk the horn would honk the horn twice, not once.
Since we're all being pedantic about HTTP methods here, we should have a link to RFC 2616 :)
I guess I was thinking of the idempotent "panic" button on my cars key fob.
But pragmatically, given the problems customs verbs cause I'd probably go for POST.
Hmmm, mine actually isn't--one hit turns panic mode on, the second turns it off.
http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-1...
PUT can be creation (not only POST), if you know the URI of the resource in question, but PUT implies that the submitted data should create or replace the resource at that URI, and in the case of a physical horn, this is impossible. I don't think you should ever be able to PUT to something that it's impossible, even in theory, to create with a PUT.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
First of all, we're not "enclosing" an "entity" to be "stored" or "accepted", so neither HTTP verb is strictly appropriate.
PUT requests are for uploading a resource, and the uploader specifies the desired final URL. So PUT is only appropriate for creating a new horn. Relevant quotation:
In contrast [with POST], the URI in a PUT
request identifies the entity enclosed with
the request -- the user agent knows what URI
is intended and the server MUST NOT attempt
to apply the request to some other resource.
If the server desires that the request be
applied to a different URI, it MUST send a
301 (Moved Permanently) response; the user
agent MAY then make its own decision
regarding whether or not to redirect the request.
POST requests, by contrast, are sent to a handling resource, which decides what to do. POST is appropriate for several purposes, including "annotating existing resources" and "providing ... data ... to a data-handling process". Seems like a better fit.But either way, REST is for documents (understood broadly), and I don't think I know how to understand "document" broadly enough to cover a horn. So it's gonna be a rough stretch, and in general, I'm skeptical about the value of applying REST semantics.
That's probably about the wisest thing that's going to be posted on the subject tonight. I did a large enunciator panel project and we ended up being "rest-ish", using the idempotent PUT to put hardware dodads into various states, and reserving POST for adding things to execution queues. Being clear and consistent is probably the silver pearl in any implementation. Hardware control always degrades to some kind of RPC scheme, even if you dress it in a REST outfit.
One must at least take the basic protocol promises into account. And there is no certainty that a GET will reach its destination, nor that it (or a PUT) will reach destination only once.
But HTTP is not REST (note that SOAP usually layers over HTTP, although the SOAP-vs-REST is an unhelpful dichotomy).
As some other commenters (including an uncle of this comment) have said, what one often wants is simply RPC, and one must pick (or roll) an RPC format. JSON-or-whatever over HTTP seems good to me, and yes one must be respectful of HTTP semantics.
In fact, aside from the very-troubling choice of GET for commands, the API linked seems entirely reasonable. And it's not RESTful at all (in ways far deeper than verb choice). And that's a good thing.
Also, which server are they using? That alone is an interesting fact, as it has to support tens of thousands of simultaneous connections...
Many of the other car manufacturers provide remote access to cars. See GM's OnStar, Ford's Sync Services, etc... One of those companies used to advertise on TV you calling them and having them unlock your car remotely and IIRC starting the engine.
Personally, I'm not too fond of my car being accessible remotely unless it's me who has control over that access.
I would bet five Zimbabwe dollars that most systems of this type can be used to control the cars of non-subscribers if taken over.
Keep in mind this isn't for the telematics, which are an entirely different system. This just gives you a view into some parts of that system. This is primarily used by the mobile apps, so the activity level is likely much lower than that.
I remarked how non-RESTful this API is, which may have been the motivation for the title of this submission [2].
Why wouldn't it be acceptable? Can you think about any reason? Because I can't. (And you could reach some very nice API independence by carrying RPC metadata at the REST API.)
The only thing I see here that I think is wrong is that the API uses GET when it should use other verbs. But lots of people already pointed that.
This API makes me want to have a Tesla. There are so many interesting apps/utilities that can be made with this!
/vehicles/{id}/snooplion/hydraulics/bounce
is idempotent or not?