Where REST back-ends and APIs overlap
First, foremost, and possibly even most important, very little changes about securing your code, whether it’s an API or just a plain old back-end. You still have to make sure there’s validation that a caller is authoriRezed to access the resource before returning data, you still need to make sure you’re not leaking personal data, and you still need to be preventing access to your endpoints to everything except authorized callers. Everything you need to do in order to secure your API endpoints works for application endpoints, and is needed for the same reasons.
Also worth keeping in mind, while we’re talking about similarities between REST back-ends and APIs, that there’s nothing stopping someone else turning your REST back-end from into their own API. Your endpoints are visible in any browser’s built-in dev console, along with request and response payload. The only thing that’s not exposed is how authentication tokens are generated. This doesn’t obligate you to keeping the level of backwards compatibility that comes from intentionally running an API, but you do need to keep it in mind when securing your calls.
API or not, you still need to be using proper HTTP methods, status codes, and other general HTTP conventions. Front-end HTTP clients are built to check the HTTP response status from server calls and catch non 2XX HTTP responses. All of that falls apart when you refuse to use them and return success codes for failed calls. Your code, whether API, or server, becomes much less readable and consumable when you violate the standard practices people calling it expect to be in place.
The only thing that an API has that a RESTful back-end doesn’t is the requirement for consistency in the endpoints for long stretches of time. Even if you do making a breaking change in an API, you have to support the old version that people are relying on long enough for them to get around to updating their code. As a reminder, that’s tech debt work, and a lot of us know how highly a lot of business prioritize that.
Where APIs break off from RESTful back-ends
The truth is, an API looks a lot like a service back-end with better long-term support, more formal versioning practices, and better documentation. The real difference between an API and a REST back-end is that API clients aren’t just a web page, but oftentimes they’re applications running on servers by other teams, often in other companies. That’s why it’s so important to make sure any changes you make to an API don’t impact users until they update their codebase – nobody wants to have to fix their code because you can’t limit the side effects of your changes to the separate repo you wrote them in.
APIs are designed to solve use cases that aren’t your own, and the only real tools you have to control how other people impact your systems are the endpoints you expose, the rate limits you impose, and restrictions on specific clients (if you don’t believe that APIs can be used for things you didn’t design it for, read here for how some former co-workers and I turned a multi-million dollar enterprise B2B email marketing platform into a notification engine for asking people to set out more snacks in the kitchen). Another important thing you can do with APIs is to build bulk operations into the API at every step you can. In fact, I’m starting to think that APIs would work best if we just started building them as bulk operations from the outset, and then just let callers submit collections of size 1 if they didn’t need bulk actions.
API calls into your system are intended to perform an action on your end, on behalf of another user. If they need the same action performed on a lot of items on their end, they’re going to write a loop. Why not just let them send collections, and then you process those as parallel as possible? Worst-case scenario, you’re writing the loop. But it’s inevitable that somebody’s going to need to run something on a lot of data, so you might as well prepare your endpoints for that eventuality. With a RESTful back-end, your only client is going to be your application, so you have a lot more control over data volume per caller.
Outside the technical aspects of implementing an API, there’s a lot of work that goes into operating that API. You need external documentation (even if you’re just making an internal API, you still need documentation that’s designed to get people outside your team started), and utilities to onboard new users. You need to be able to support multiple API versions at once (people need time to migrate from 1 major version to another). Not having to do that anymore was a major reason companies who traditionally shipped installed software moved to cloud applications (that, and all the money that can be made from recurring monthly subscription revenues). While you may be supporting multiple API versions, you have to commit to a end date for that support (something that most business-facing and customer-facing people are often loathe to do), and actually turn off that API after that date. Yes, part of API support is announcing to users that you’re not going to support a product on the grounds that it’s really old, and then actually break the code of the ones that call your bluff.
Just because your server has RESTful endpoints that are returning JSON doesn’t mean you have an API. The fact that you don’t have an API doesn’t let you off the hook with regards to good back-end engineering. Admitting that your back-end is just a REST server and not an API gives you the freedom to make breaking changes as-needed without committing to supporting other teams/outside developers by keeping multiple versions deployed and running. Good back-end engineering is the start of a good API, but there’s a lot of other work that goes into APIs that your use case likely doesn’t qualify for. In those instances, embrace the flexibility that gives you to refactor your endpoints and contracts when the situation arises. If your situation requires that you offer an actual API, just remember that the associated front-end is really the least of your API’s concerns.