Designing an API using OpenAPI and going through modeling, mocking, etc. can save you wasting a bunch of time building the wrong thing, and having that OpenAPI can speed you up along the whole API lifecycle as you build the API and write tests, but is it always necessary? What if you don't want to design an API? What if you don't want to even build one? Is this a good idea, or are you a lazy bad developer?
I am proud of my part in helping the API Design-first workflow go from relative obscurity five years ago, to a place where it's being adopted by teams all over the world. I've worked on infinite tools, helped rewrite chunks of specifications, spent years working on education in the space, so you'd probably expect me to use API Design-first for every API right? Wrong! Sometimes I completely ignore the whole concept. 🤯
There's an old Spanish proverb "the cobbler’s children have no shoes", and it basically means sometimes the expert is so busy helping others that they're too tired to sort out their own problems. It's why my chef friends knock out microwave meals when they get home from a long shift. It's why some hairdressers have shockingly bad hair, It's also why I've been using Airtable to make APIs instead of designing and building top quality APIs.
Use-case Drive APIs vs Data APIs
API Design intentionally takes a bit more time earlier on in the process. Think about the domain, split up various models into resources on distinct endpoints, start adding in some methods, headers, payloads, all the whilst looping in stakeholders to make sure the APIs do what you want.
This is exactly what you need to do for Use-Case Driven APIs that may have complex workflows with predefined paths and "next available steps" available through HATEOAS links, but if the API is a "Data API"... do you really need to plan out that you're going to Create, Read, Update, and Delete each of the Things in your API?
Sitting there and writing a
delete() for every controller is mind-numbing, and no amount of "generators" or "scaffolding" can save you from this pain.
Then there's the whole faff of building a CRUD admin interface to go with those CRUD endpoints. In 2006 I remember Rails telling me I'd never have to do this again, and it was never true.
Skipping all that CRUD
In 2020 my reforestation startup Protect Earth needed a simple iOS application to photograph all the trees we plant, and save a bit of metadata about species, supervisors, GPS coordinates, and a photo. This would help us keep track of all the trees we planted, and hook them up with Organizations paying for them through Orders to support our work.
If I was going to design and build this API I'd start with some CRUD API endpoints:
I'd then bash together some MVC application with a database that has tables for all of those entities, and build the 12,096th admin panel I've had to build. Then it starts getting a bit trickier: I've got to handle image uploads, which is a bit of a faff now that I have to set up a Amazon S3 bucket, set up some access tokens, make sure my API is configured to support it in both dev and production.
Soon I'll likely need to make custom views for those organizations to see various reports, and set up Slack alerts for new orders. This is all a whole lot of code I need to write which is taking me away from the woods/bike/pub.
You can see where I'm going with this. It's all a bit of a faff, and with almost zero budget it made no sense at all for me to spend months doing it all the "most proper way" possible when there was nobody there to judge me. I didn't need to build a shining castle on the hill, I needed to build a simple cabin that would get me through winter as snow was falling all around me.
With more no/low-code solutions popping up it was incredibly simple to pop this all together. After trying out a few headless CMS at the easy end, and Firebase at the more complicated end, I settled with Airtable, which had a super simple API, let me muck about with it programatically, and had enough integrations baked in I could spin off a Zapier, Pipedream, or Make for anything I needed to tack on in the future.
The API might not have been super lovely, but it was fine enough for our iOS developer to work with, and our iOS app was build in record time uploading images and data to Airtable. We got out there photographing all our trees, building up that dataset ready for the next stage.
Our funding partners had particular ideas about what the API should look like, and throwing them directly at Airtable apparently was not going to work. Alright, easy, we just made a simple proxy API that would mush the Airtable API data into the format they wanted. No complicated logic, just turning some JSON into other JSON with an AWS Lambda.
The Arc of the Universe Bends Towards Design & Code
Airtable served my charity well for two years until it started to creak at the seams. Too many records in some bases, photos too big, too many automations being triggered, not enough granular control over permissions for views, etc. Fair enough, two years of service were massively appreciated.
Making a wrapper around Airtable had given us a huge amount of flexibility for a migration to anything else, so long as the new system was mushable from some datasource into the same JSON our partners were expecting.
We ended up going back to my roots, and building the API using Laravel (PHP), but deferring all the admin panel work to their powerful low-code solution Laravel Nova. This was more configuration than coding, and helped with CRUD forms and image uploads nicely. As it is basically a standard PHP application that supports whatever database system and cloud filesystems you want, it meant we could migrate our data from Airtable into MySQL (Amazon RDS), and move our images from Airtable into S3/CloudFront.
Consider the Exit Strategy
The migration from Airtable was admittedly a bit of a faff, and its made me think a bit differently about how I might want to do this in the future.
AWS Amplify for example would let me just have a RDS database right there, and I know how to handle that.
Google Firebase has a fancy sounding Google Firestore, which I am sure is absolutely brilliant once I figure it out.
DreamFactory would let me hook up whatever data source, including things I've never heard of, so I could build whatever as a database then just have it do the API magic for me.
All of that lookedl ike it would need a bit more learning than I had the mental capacity for whilst also trying to learn about reforestation grants and different saplings and infinite other stuff, so I punted it, and went with the easiest thing I could find. That might not be the right approach every time. There is an art to finding the tool/platform which can solve your needs right now, and finding a tool/platform that you arent just going to outgrow before you have capacity to replace it.
If you can find something that's likely to cover your needs as you scale, you can have your cake and eat it too, and whilst I didn't have time to evaluate that all before, I'd like to spend some time delving into various tools to help you make those decisions for upcoming projects.
Data-first is ok for Data APIs
Design-first is mostly helpful at avoiding change later down the line at more expensive parts in the lifecycle, like getting a team to rewrite all their controllers and models to some new name you decided, but with most of these no-code solutions you just rename a Model and it's all done for you, so long as you've not got a plethora of clients all suddenly broken by the change then that's not really an issue.
These data-driven approaches can save a whole lot of effort in scenarios where you don't need all the bells and whistles of a shiny hand built artisinally crafted API.
Many of us API experts have said infinite times "Your data model is not your API domain model" and that is usually true, unless you are literally building a Data API. In which case... it might be. Sure you don't want to literally expose every single relationship and pivot table exactly as it lives in your database, but you don't need to get massively creative when you just need to get that data over the wire in a sensible way.
If you're in a startup or working on an experimental idea, low-code or no-code could really help you focus on delivering functionality for your customers so you can extend the lifeline of your company instead of wasting time you don't have rebuilding various wheels for the umpteenth time. It can also help spin up prototypes in larger businesses, proving an idea before you're able to get buyin for larger efforts. Perhaps you can use these tools well enough that you can outlast "rough experiment" and get into "pretty useful for ages" territory, before commiting huge resources to going the entirely custom and extremely well planned approach, and when you do, you'll have all this experience to build from.