Last week I attended the 2014 API-Craft conference in Detroit - and I had a great time! Met lots of interesting people, had great conversations and learned a lot about what other people make out there.
Some of the stuff I saw and listen to in Detroit made a few pieces of puzzle click together in my brain. First there was Z who reminded me that we still don't have any good description language for documenting resource oriented hypermedia APIs. I've heard that before and been wondering how it would look like.
Then I talked with Sergey and Dmitri who showed me the resource diagram for their API - this one reminded me so much of UML diagrams that I think we should look into that for inspiration.
I was also at the "Documenting APIs" session where I suddenly found myself talking about our own API documentation - which is written in Word (and that's okay, kind'a). It made me realize that, at its core, such a documentation consists of resource descriptions, link relation descriptions, action descriptions and of course some kind of overview, introduction and tutorial sections.
Someone asked us to explain what a hypermedia API is in one sentence. I came up with "That is an API which can be documented without writing one single absolute URL or relative URL path". I don't exactly think that will catch on, especially not outside this community, but I do believe it is true - if you need to explain URL structures then you are missing something. Unfortunately that one sentence doesn't tell you how to actually implement such an API and as such it is really not very useful.
[I'm pretty sure there is a good Yoda quote to put in here ... like, you now ... "The links with you very strong are here, Luke". Anyone got a better one?]
Dave introduced me to his JSON based description language for APIs and it made me realize that you can do awesome things even in a dead simple format like JSON. Why having to state <twice>everything</twice> when you can do { "single": "everything" }.
Then there were people talking about resources and state machines (thanks again Z). Personally I don't believe much in that analogy - it kind of confuses the graph of resource relationships with the graph of a way-too-simple-never-to-be-found-in-real-life state machine. Z did try to convince me about this but never succeeded - maybe because I am highly colored by my PhD thesis on automatic verification of obnoxiously great state machines :-)
We also got a great deal around API explorers/browsers of various kinds. It seems like every media type have such one now a days - and it makes great sense to me. I truly believe in the power it has when it comes to learning a new API. Thanks to Kristopher Kleva for his story about links, actions and the Sirene browser (you really should blog about that experience!).
I also met Pete Gamache who is the guy behind HyperResource - unfortunately we never really spoke together. He's hypermedia client for Ruby is an interesting solution for interacting with hypermedia APIs in code. Its not exactly new as the same kind of ideas exists in the older tool Restfulie (for Ruby) and my own Ramone library (for C#) - but none the less it shows that there are something worth pursuing here.
All the talks about tooling, SDKs and object models for API resources made me want to work a bit on Ramone and Mason again. It could be cool to make a C# hypermedia resource representation that would allow the client developer to follow links and execute actions in an easy and intuitive way - while at the same time be able to hide some of the stuff that complicates client code in order to make it long lasting and handle (some types of) API changes.
So, thanks to all of you - also those of you that I have forgotten to mention here and of course the people at Apigee that made all of this possible!
Jørn, have you used an alternative approach instead of state machines that has worked well for you when you have many possible states that you can modify a resource?
SvarSletThanks,
Magnus
Well, I don't think of resources in terms of state machines - and the frameworks I have seen doesn't either. Usually the code is like this:
SvarSlet1) Framework calculates route
2) Framework calls request handler
3) Request handler does, well, request handling (the business stuff) and returns a result
4) Framework does content negotiation and delegates to some sort of render/codec/view-handler
5) The render, well, renders output in accepted format.
Step 3 would be the "state machine" - but what it does here is to load a bunch of different internal objects/entitites/DTOs/what-ever, reacts to any incoming payload, and builds some kind of internal result representation. That is similar to a "Pre state value", a "Transition" and a "Post state value" - but not on one single easy-peasy state machine, no, its a sh*t load of internal objects/entities/DTOs/whatever that are modified.
The "state" here is the collection of internal objects/entities/DTOs - and they have MUCH more than just one single three-state variable to define the collective state of the resource.
For instance, at work we have a "record" object which has a bunch of variables - one being status = "in-progress/closed", another being accessibility = "public/related-users/private", a third being deadline = "some-date-time". This would correspond to two state machines with 2 and 3 states plus something which is not a finite state machine (although in practice it has 2^64 states if the date time variable has 64 bits).
All of these three variables/states define behavior and restricts the available set of actions and links at one instance in time. In addition to this, any action that modifies a resource may easily change a large set of variables/state-machines at one time.
Trying to model this in a strictly state machine kind of fashion with circles indicating values of different variables/state-machines and arrows between them would be horrible.
I think it is much easier to think of a resource as a set of variables that can be used as a set of enabling conditions for another set of links and business actions. State machines are simply to low level to work with - its like trying to implement the whole API in assembler.