previously, https://cohost.org/tef/post/219290-api-design-mistakes
with programming, there isn't so much a right way to do things, but there are an awful lot of bad ways, and the best you can do is try and fall into a new mistake than repeat the same ones, over and over.
then again, when you make the same mistake over and over, you call it a best practice, and sometimes doing the right thing ends up being the wrong choice, because no-one understands why you're doing it.
welcome to hell, no matter what you do, someone will tell you it's wrong.
this is yet another post where i present my opinions and tradeoffs in design as near absolutes, but hopefully i'll explain the reasoning behind them. i don't expect you to follow my dogma, but i do hope that you'll understand the consequences of your own api choices a little better.
honestly, most of this just comes down to taste
A thing that drives me up a wall as a maintainer of a Slack client library is when responses share structure but they don't document this. So there's like, shared types, such as "user", "message" etc that exist but they don't write it down. Oh, but sometimes they're cute and don't include "is_member" on the "channels you're a member of" api call because it's obvious or something, which means dear me is needing to make it Maybe in the shared type for channels when it's always sent otherwise. Don't do this: just always put the field in. Always serialize the same schema type the same then document it in one place.
Also more generally they just provide an example of calling the api from 2016 with little description and you get lots of bonus fields if you collect new data. I have an extensive snapshot test suite where I just collect examples of every message they've sent me in a test workspace. I also accidentally started just parsing every message event in a busy slack workspace and collecting parse exceptions which has found several schema bugs.
For a service who does actually offer an api, I'm doing a shocking amount of reverse engineering regularly.