These days, it’s a rare occurrence that a web-based application is only ever going to remain web-based. What starts as a website usually ends up taking on a life of its own and expanding into mobile apps, GUI-based interfaces, and so on.
Unfortunately, the vast majority of websites are still built with the old “web-only” approach in mind—which, in today’s world, introduces by-design limitations in what your software can do: when the client comes calling and asking for, say, an iPhone version of your application, or a client-based management console built in Flex and AIR, mixing your presentation and business-logic layer is going to become a very expensive decision.
To be sure, even if you—or, more likely, someone before you—has made the decision of designing “one big ball of code” from which you now have the unenviable task of extracting a viable API, there are solutions that can help make that process easier: for example, my good friends at echolibre make FRAPI, a product that makes it possible to “wrap” a web-based API around an existing codebase or data source, thus making it relatively painless to breathe new life into an old design.
Building from the APIOn the other hand, if you’re starting a new project today, there is absolutely no good reason why you shouldn’t begin your design with an API—in fact, you should make your web application a client of the API to make sure that you do not inadvertently build functionality in the wrong layer of your application.
This is exactly how we’ve built most of php|architect (something that I have, at some point or other, already explained in this blog): we have a “service layer” that is physically separate from our many application layers—in fact, it now resides on its own server for performance reasons and to isolate our frontend, where we run software we have no direct control over, like WordPress, from our backend.
We draw a number of advantages from this approach: first, we never duplicate code; if a function is used in more than one place, I assure you that it’s always performed by the same script. It might look and behave differently based on a number of different reasons, such as ACLs and interface, but the underlying code is always the same.
Second, we can build as many different frontends as we need. At one point or another, we’ve had a website, iPhone app, iPhone website, various conferences websites and our Flex-based management console all running from the same service-layer codebase. We have even built specialty services for some of our partners who need (for example) to sign PDF files—and, in all cases, not a single line of wasted code was written for the backend.
Third, our code is safer. This is not because we are necessarily better at writing code, but because we have a single system to keep secure and because any problem only ever needs to be fixed in one place.
APIs should be platform agnosticDevelopers seem to confuse APIs with the protocol through which they are exposed. If you tie your API to a particular protocol—be it REST, SOAP or whatever else, you are needlessly limiting your options. The API is simply the interface between your application (the backend in this case) and whatever frontend happens to be using it. In many ways, if you think of your backend as its own application, the API is essentially the controller and the protocol through which it is accessed is the view.
If you keep API and access layer separate, you can easily provide support for multiple entry points, which means that whoever needs to develop against your code will have the option of choosing the best solution for their needs. For example, you can implement a RESTful interface based on JSON for AJAX, a SOAP interface for web applications and, say, an AMF interface for Flash/Flex clients.
Control is the keyObviously, multiple entry points mean multiple potentially vulnerable points as well. That’s why the best API implementations ensure that access control resides with the API, and not the entry point. If you delegate that task to the entry points themselves, then you will always have to make sure that their support for security is always in sync.
For example, AMFPHP supports authentication and ACLs in the method table for a given service—a great way to take advantage of Flash’s built-in access management and error reporting. On the other hand, it pays to build your own ACL system and then integrate AMFPHP’s with it, because you will then be able to support different entry points without having to rewrite the access layer, too
At the end of the day, whatever the approach you take, building API-centric systems is a clear winner—particularly if you ever want third parties to connect to and use your data. Even if you ever only build for your internal use, an API layer comes with many advantages that will make your life easier in the long run.