Saturday 3 December 2011
Architecture - the shape of the system, the patterns used - is by far the most meaningful thing to get right in any system. Architectural decisions have far more influence on the capabilities and limitations of any given system than the implementation decisions - frameworks and languages - ever can.
This effect is hugely magnified when you're building a platform, because you're creating tools and raw materials for other developers, and your decisions can enable them to easily build apps any way they can imagine or limit their options to a handful of pre-configured choices.
Side note here; the internet is becoming full of platforms. It has never been easier to programmatically consume services on the web, even through interfaces originally only intended for humans, and combine existing data in new ways to create whole new experiences. You might put an app out there for customers, which you consider to be a finished product, and then discover that someone else is using your app as a building block in their app. One man's front end becomes another man's back end. I think this is a good thing for momentum and creativity; allowing new takes on current ideas to be spun up and explored quickly and cheaply.
But if you intend to build a platform, if that's what you're explicitly setting out to do, then there are some design guidelines which will lend it greater commercial utility. Not patterns per se, more like principles, which I'm going to call the 5 laws of platform architecture:
1st Law of Platform Architecture - the value of a platform is directly proportionate to the amount of work it causes to be unnecessary.
Most web businesses are more similar than they are different. There is a set of web basics they all need (identity, profile, cart, payment, analytics...) and there are usually a set of line-of-business basics that most of them have in common (in my case that's things like inventory, price, geography, booking, weather...) and that's an awful lot of code that we're all writing. If a platform solves the 'common problems' via a handful of simple web service calls, then partners using said platform can put the majority of their time and passion and investment where it will make the biggest difference to their business; building the unique features which distinguish them from the rest of the marketplace. I like to ask "what don't my partners have to do because we already did it?" and I like to have a long list of things to put into that bucket.
2nd Law of Platform Architecture - ease of adoption maps directly to business momentum.
Most serious platforms are monetised in the same handful of ways, and in most cases the sooner you can have partners up and running the sooner you're counting revenue from them, ergo time to market for your partners is a lever in your own P&L and if you focus on ease of adoption you will bring on more partners, they will each 'go live' quicker, and it is cheaper than more traditional incentives such as offering improved commercial terms in exchange for faster rollouts etc. The kinds of things you ought to consider here go beyond the simplicity of the services you expose (which must be easy for the most pedestrian of developers to grok - in the platform game you are penalised for externally-observable complexity) and into how much you invest in documentation, SDK and client code, and developer community support. These things pay you back.
3rd Law of Platform Architecture - entrypoint depth multiplies the business flexibility of any given service.
Higher layer abstractions always infer business logic. That's what a composite service really is; someone decided that for use case alpha, you always do X then Y then Z, and therefore aggregating calls out to services A and B and C solves that problem in a single call. You have just created a simpler solution for alpha - which is an admirable achievement and it belongs in your platform exposed to everyone else who has use case alpha. But let's say I have use case alpha prime? A basically similar business process but with key differences that no longer require data from B? That's why your underlying services belong in your platform too; if a client has some business logic which maps quite closely to the higher layer abstractions then that's great orchestration for that app. If a partner want to do something a little different, then he might have to consume those composites and do a bunch of his own transformations on the data, perhaps even store the data himself, and then present it to the client apps through his own interfaces. With the option of consuming services from lower down the stack clients can build unique apps on top of the platform with far less 'back end' work (stripping out the inferred but irrelevant business logic) on the client side.
4th Law of Platform Architecture - compute work becomes exponentially cheaper and faster as it approaches the edge.
At last something more technical! If you're building a platform, and you're not planning on comprehensive global coverage, then I would question your commitment to your idea on a web where ubiquitousness has never been cheaper to claim. So let's assume that you are doing this globally. Without getting into a discourse on distributed systems, you're going to want to deliver straightforward and performant access to every consumer regardless of where they're based. That is a distributed system problem, and so your platform should run on a system with a diameter greater than 1, and you should try to service requests as close to the edge (and as high up in your stack) as you can. There are plenty of mature grid and edge computing infrastructures out there to provide the scaffolding for this. What does it mean for your partners? They're using a platform with better durability and lower latency than alternatives that they might choose, which translates into better SLAs and better service which also happens to be cheaper to deliver.
5th Law of Platform Architecture - as services become more atomic the addressable market segments become more broad.
My 3rd law deals with entrypoints, and this is nearly the same thing. Lower layer abstractions allow platform consumption without constraining the use cases, but another critical property of those granular services is their atomicity. Your low level granular services must perform generic, stateless (independent) operations, all be individually consumable, and each should be of business value individually. When I say individually consumable I think I really mean individually usable. If one has to consume a handful of other services to be able to make sense of the data returned from a single service, then it clearly isn't too useful in it's own right. Perhaps it needs slightly more data or metadata around it or maybe it is just noise in your stack - keeping the catalogue manageable is actually a harder problem than it may seem. When your lower layer abstractions are individually useful you find that more kinds of businesses can make use of them. To round this out with an example; exposing our geography data distinctly (i.e. outside of a composite which applies it to a booking flow) enables us to power navigation and mapping apps, instead of just travel apps.
These are guidelines for architecting a platform to maximise its utility to developers and its commercial success as a set of business building blocks for a range markets. But what about the shape of the system(s) behind each service? That dimension of architecture - how you manifest each of your APIs - is just as important.
We all have our favourite ways of doing things, and pushing one pattern over another without an understanding of the business problem and environment is just bad science, so the best I can do here is suggest establishing some engineering principles to give engineers a decision making framework within which they can own the problem and still consistently meet the higher standards expected from platforms. Scalability, Maintainability, Quality, Security, Availability, and User Experience have always worked for me.
Whatever you do keep in mind that if you operate a platform, then you're partly responsible for the availability and integrity and brand and revenue of n number of businesses (i.e. the partners building their apps on your stuff) so you have an even greater responsibility for quality than you do when your building your own customer-facing apps. I'm a pretty casual guy about most things, but that's a responsibility I take very seriously indeed...