Crafting Code Podcast
$ cd episodes/055-api-categorization
~/podcast/episodes/055-api-categorization $ ls -1a ~/podcast/episodes/055-api-categorization $ cat episode-summary.txtKnowing your audience is good advice for APIs, not just public speaking or selling your ideas. Providing separate APIs for different purposes can make each one much easier to manage, especially when it comes time to roll out updates. In this episode, your hosts discuss how we like to categorize our APIs, how we deal with versioning, and why you might want to follow these patterns too.
~/podcast/episodes/055-api-categorization $ cat themes.txt ~/podcast/episodes/055-api-categorization$ cat transcript.txt
[00:00:16] Allan Stewart: Welcome to the Crafting Code Podcast, where we discuss the importance of doing the right thing at the right time with the right tools. I'm Allan Stewart, a software architect. Tech. Lately, I've been thinking about the need for a foundation of principles and intentionality when trying to create or alter a culture.
[00:00:34] Dave Adsit: I'm Dave Adsit, a VP of engineering, and I have been thinking about lean, Agile, Scrum, product strategy and the importance of aligning incentives to desired outcomes in an organization.
[00:00:48] Allan Stewart: Our topic for this episode is API categorization. This is a a topic that, or a concept that you introduced me to, Dave. So tell our listeners, what do you mean by categorization and why would you want to do this?
[00:01:02] Dave Adsit: Well, APIs are a very common thing in software development. We use APIs for everything, right? We expose APIs to our customers. We expose APIs between our systems. We consume other people's APIs. And each of these APIs for me fits in a different category, whether it is who the consumer, who the intended consumer is, is one axis. And what is the level of visibility is the other axis for how I like to categorize APIs. Yeah.
[00:01:39] Allan Stewart: It's kind of the programming analog to knowing your audience, or at least that's how I think about it. Like there are times as, as a software architect, where I have found that there is the same concept or same problem that I have had, and I need to present it differently depending on who my audience is. So if I'm, if I'm presenting to developers and say, "Hey, this is what we're trying to achieve as a bunch of developers," then they need a different level of detail. They need a different kind of information information than when I'm talking to product managers, or then when I'm talking to an executive team. The same kind of concept comes up in like public speaking, right? Knowing your audience is an important way to be able to communicate effectively with them. And I, and I feel like this is a kind of a programming analog to that.
[00:02:26] Dave Adsit: I agree it. And it, what it really comes down to is what are the needs and capabilities of of your customers, your consumers, your API consumers, the people this API is for. So if we just jump right into it, the three different types of consumers I think of when I categorize APIs are first, our customers. When we think of an API, probably the first thing you think of is I'm going to build an API that's externally available for our customers. It's reporting API. It's an integration for API, something that our customers are going to use. And, and there's specific requirements and constraints that come with building an API that's going to be used by the companies or people that you sell your product to. The, the second level is, or the second category is the system API. And those are APIs that we're building, not for our customers, but for our internal use. So we're building a microservices system. I run a service, you run a service, you need something from me. I expose an API that you can then use, right? That is the second type. And the third, I call the context, the bounded context, the context, maybe the team API. And those are APIs we make for ourselves. So in this case, I'm talking about, I've got a microservice that I'm building, and you've got a microservice that you're building. Well, my microservice has a front end, and that front end needs to be served data. And I'm going to serve that data through an API. And now we've got three different types or categories of API that each have different characteristics.
[00:04:09] Allan Stewart: Right. And in that final one, the context one, because it is the team that is owning it, this is the case where you're writing the front end and also the backend, right? Right. So that's one axis. The other axis is the visibility, right? Right. And this basically is just, is it accessible on the outside internet or do you need to be on some kind of like internal VPC or something to access it? Right.
[00:04:37] Dave Adsit: Yeah. Yeah. That's the other category is I, when we're deploying to a cloud or an internal data center, some of the stuff that we build is only accessible if you have direct access to our network. And some of it is just out there in the internet in the wild, scary world. And so that also gives us different constraints, right? The way we build an API that is only internally routable and accessible, we're going to probably treat security a different way. For example, maybe we're going to do pre-shared private keys or secret keys versus building a fully robust authentication and authorization system. Maybe we say everybody who has a key, everybody, like we have four consumers. So if it's a system API, we've got four consumers, each of them got their own API key. We can track based on key, who's using it, whatever. Easy peasy. And if I put it on the public internet, I'm gonna have to be pretty careful about who I let access this and how so that they don't do nefarious things with our data. Yeah. So given that you've got two axes, three by two, that's six quadrants, quadrants, six areas that an API could fit in. Yeah. Five of those make a lot of sense. And one of them is kind of, I'd like to see it, but I haven't. So we can have either a public or private bounded context API that's owned by my team, used by my team. It's internally routable or externally routable. Great. We can have a public or private system API. Sometimes parts of my system might need to route traffic through the internet. Sometimes they route traffic internally in my data center. Both of those are very reasonable. And then we probably only have a public customer API because if it's an internal or private customer API, how do they get access to it?
[00:06:42] Allan Stewart: Right. Yeah. And I think, I think there's good reasons for various ones of those, right? So like, even though your team context level API shouldn't really be used by anybody else, right? Like your team is the only one that should really be accessing it. It's going to happen probably from like a web or a mobile front end of some kind. And so it has to be publicly addressable, you know, so that the browser can actually connect to it. So it is public. I think you originally termed it as public and internal. I think that that's better than public and private in some ways, because it's your public context one might still be private in as much as you're not letting other people use it. And like you said, it might have a different, you know, each one of these have different ways that you access it, right? Different security measures, right? And so like with the context API that's powering a web front end, you might have some kind of like a different bearer token or even like a authentication cookie that is shared across many parts of your entire system. And that is treated differently than, say, a system API or a customer API that has a different kind of security pattern. And then there's other things that go along with that too, right? Like, where does the data come from? What kind of caching is available? If you've got like a reporting API for customers, it might not be, you know, real time up to date. It might be just, "Hey, as of, you know, every so often, like, you know, we've got like a rolling window, like every, every day, you know, that anything is up to date at least since midnight or something like that."
[00:08:26] Dave Adsit: Close of business yesterday. Yeah. Right. Yeah. So let's take a dig in a little bit more on the differences between the consumers. The reason that I like to create a context API specifically is if it's owned by my team and only accessed by my team, there are no constraints on how often I change it. Not really, right? If I'm doing continuous deploy, continuous delivery, I'm shipping code five times a day into production, I can change the shape of that API every single time. All I have to do is deploy the API and the front end together. And because I know there's no consumers, but us, it's okay. If it changes all the time at a very rapid case, a very rapid cadence, and that allows us to do some interesting things. Like I can follow the backends for frontends pattern where I, in that pattern, I say, "Here's the front end that I need. And it needs these data, this data to like fill the form, whatever. Ever. Okay. I'm going to create an API endpoint that returns that data and exactly that data with nothing else." And I know I can just change it as the front end changes. If the UI changes and I need more data, I can add it. If the UI changes and I remove data, I can remove it from my response, my backend response and the backends for frontends pattern where I custom build that backend end response to meet the needs of that front end as it exists right now. And that allows us to have really, really lightweight responses. So that can be more efficient. It can be better on mobile,
[00:10:14] Allan Stewart: et cetera. Right. And you can choose how you want to aggregate data for certain calls because, hey, this, we know exactly the purpose of this particular page or the reason why it's being being called. And so you're, you're tailoring it to your exact need rather than kind of an arbitrary. Like, I think over the years I've encountered people who want to do, you know, a really pure or true REST functionality. Right. Yeah. Or, or another example is I've seen a lot of people who are like, well, you have an API and so therefore you must have the automatic API API documentation that with some frameworks, it even comes out of the box, right? It's like, "Oh, well you set up these routing endpoints and whatever." And like, "You just get all the documentation tools to go right with it." And, and I always look at that and I say, "Well, if this is a, if this is a context API that you're just using with your team, you're building it and you're consuming it. What need have you of all this documentation?" It's just like, it's just extra weight. Wait, it's extra noise. You might get it for free, but as we all know, you know, there's not really a free lunch.
[00:11:30] Dave Adsit: I've used some systems that had those before. I've worked on systems that use those types of tools before. And we always turned them off in production because you never know what somebody is going to do if they get access to that documentation. And so it wasn't really super useful to us anyway. Right. So, so that is that if you have that dedicated API, which you probably probably do if you're building a web application, it's, it's got some really nice characteristics that allow some really good development patterns. Uh, if you're building a more complicated distributed system and you start building system APIs, then you get some slightly different behavior and constraints, right? So if I've got a system API, one of the things that I want to basically, because I'm exposing that to other teams, presumably I've got a big enough company, any big enough organization that I need to have multiple teams building different things. And they're going to need to share some stuff, either behavior or data or something. And I want to do that through APIs because that gives me some ability to abstract away the implementation. I don't want to give anybody access to my database. So I better build them an API if they need my data. So with a system API, I can't change it every day because I've got consumers on other teams that are doing things with that API. They're relying on it. I've basically made a contract with them that this API will be available and they need it to be available. And if I decide I want to change it, well, I can't necessarily change it because they don't, they can't necessarily drop everything and implement the new version when I want to ship it. So now I've got to introduce some more complexity to the API interaction. And that means probably what I want to do is track all of my users. I said earlier that I want to give every consumer a different API key. And that's for a couple of reasons. That's for partially for security, but partially that's so so that I can track who is using which versions of my API. Right. And when I ship a new version, I'm going to probably have to stand up my vNext of the API and tell everybody about it and incentivize them to use it or ask them to use it or whatever. Say, "Please, please upgrade to my new API so I can turn off the old one. It's got this new functionality that's going to make things so much better. Please use the new API." And then if I'm tracking the API keys that I've issued, I can then see who's moved and who hasn't. If I'm doing decent observability in my system, which I should be as well. And that allows me to see when everybody's on the new one and when I can deprecate the old one.
[00:14:14] Allan Stewart: And I think about that, like, it's not that you wouldn't do these things for other kinds of APIs necessarily, right? Right. Like you might want to have, for uniformity sake, you might want to have the same kind of security profile. Maybe you don't go with a shared key. Maybe you do have a whole key exchange or a lot. Or, yeah, or like create the key and you'll be able to see it once and restoring a hash or, you know, those kinds of things. Like maybe you do want that between the system and something you would allow customers to use, right? Which is the final category we're getting to. But the communication pattern is different. Yeah. Right. Like you can communicate with customers, but it's, it is different. There are different expectations, especially when it comes to change management than what you have with a system level API, where, because it's in the system, these are all people that work for your same company. And they are, you know, those teams are not always incentivized and aligned towards the same objectives, right? Because they're spread out into different teams. And so they're doing different things, right? And they have different bosses that are asking for things. But as a company, you tend to be more aligned than the alignment of some other third party that you may not even know really who they are, especially if you're allowing for things like, "Oh yeah, just, you know, auto-generate your API key and go to town and have fun with using our API," right? Like you might not have a clean way of communicating with all of these people and letting them know about some kind of change that you want to perform.
[00:16:03] Dave Adsit: Well, and if you think about it, you've got, for your system API, you've got between a handful and possibly on the up-rent dozens of consumers. Worst case scenario, most of your users have moved to the new version and one is hanging onto the old version. You can go crash their standup or, you know, you know, their boss, you can take them to lunch and say, "You know, it'd really be helpful for our department if your department would. Upgrade to our current API, you know, you're missing out on all of these fun." You know, you can apply some social pressure, right? There's a lot of things you can do inside the system because you are part of one overall system. Whereas when you get to the customer APIs, you're talking hundreds, thousands, even millions of consumers of that API. You're going to have a lot harder time tracking them all down and getting them to move.
[00:16:55] Allan Stewart: Even if you're observing, right? If you have really good observability and you can see, oh, yep, we know it's these customers. There's still limits to what you can do, right? Like, I guess, you know, send them an email, right? Or you can get really clever and start building things into your API. Like, oh, if you're too far, you know, after you hit a deprecation date, it's going to stop working. Or like you start getting some kind of a 400 error percentage based. And, you know, you start getting them a few at a time and you get more and more and more until finally it's just shut off. I think there's clever things you can do, but you might still be breaking them and they just don't have the time or interest to make a change. And so somebody is going to be impacted by that.
[00:17:40] Dave Adsit: Yeah. So if you think about it, the acceptable maximum cadence of change is different for these different types. If it's a context API, we've already said, change it multiple times a day. It's yours. You're using it. Fine.
[00:17:53] Allan Stewart: Right. I think the only limitation there with your context level API is just the things that you own. Right? Like if you deploy out a single page app and you know that it takes a few hours before, or days even, before everybody's refreshed and they're onto the latest, well, then you might have a little bit of gap that you have to have backwards compatibility for before you make a breaking change. But you don't have to announce it to anybody. You just have to wait and then go on your way and you can make that change whenever you want without having to tell anybody else about it.
[00:18:25] Dave Adsit: Yeah. And with a system API during initial development, it's probably the same, right? We're working out the contract together. But then after I've published it, after you've integrated with it, I'm probably not going to be able to change it more than on the cadence of weeks because we have to coordinate work across multiple work streams in order to do that. With a customer API, I assert that your customers are not going to want you to change your API more than quarterly. And they probably don't want you to change it at all unless they're the one who who requested the new functionality. But if you're changing your customer facing API more than once a quarter, you're going to end up with some frustrated customers. Particularly if you are following good API versioning habits, right? We talk about your API for the context, your bounded context API. You might have to have a vCurrent and vPrevious if it takes a few hours or a day for all of your clients that you deployed to update. If you're working on a system API and you want to create a new version, my rule of thumb is don't ever support more than three. You want vCurrent, of course, vPrevious because not all of your customers have moved and vNext if you're developing another one, right? So you might have those three and you want all of your customers to be on vCurrent with a few testing vNext with you. And anybody who's on vPrevious, you got to get them to move so that you can deprecate it, delete it, and now create another one.
[00:20:05] Allan Stewart: And to be clear here, I think you mean consumer, right? Right. The consumers of your API, because in the system context, these are other teams as opposed to customers external to the organization.
[00:20:19] Dave Adsit: Yes, that's right. The customers or consumers of your API inside of your development ecosystem, as opposed to your actual customers, who you also probably want to have limits on how many API versions you support for them because your system is changing. And finding a way to support a really old API for your really new functionality is an onerous change. So I like to do those as names, maybe. I've named API endpoints according to whatever the context is, slash vCurrent, vPrevious, and vNext. Those are names that are very communicative for people inside of your system not super great for customers. They don't really know what that means. And so for customer facing APIs, I usually like to use the quarter and year that it was published as the name. And I usually just throw that in as a URL part inside of the route, which gets me to a question of versioning. If we're talking about versioning APIs, how do you version them? Do you version individual endpoints or do you version the API as a whole?
[00:21:39] Allan Stewart: That's a tough one. And I think as I have reflected on this, I think a lot of it has to do with volatility and, like, at what level do you see a lot of change? So if you've got really stable APIs that are changing slowly, I can see an argument for doing versioning per endpoint. If you're doing a context API and it's just you, well, then, yeah, you almost don't need any versioning at all. You just have to be careful that you're not, you know, breaking things, that you're keeping it backwards compatible in your deploy window. And so doing it, like, per endpoint or even, like, options on an endpoint, that probably works just fine. But yeah, as you go further further out in the scope and there's more people interacting with it, those those ways of communicating, like, it gets really confusing if it's like, "Oh no, so on that endpoint it's you need to be on v5, but you should be on v2 for this other endpoint, um, and v3 for this one." Like, that just gets confusing for people to remember. Yeah, so updating the entire API at once, it makes the communication easier and, like, the clarity better, I think that makes sense, right? And, and then I like what you're saying about how, how you name it is, yes, absolutely, we can use version numbers, right? There are definitely benefits to something like an increasing numeric version, right? It's, like, it's why semver is very popular, the semantic versioning. But I really like what you said about having information built into the version, right? Like, if I tell you that my, the npm package that that I'm using is version 8.6.2, it tells you something, right? Like, yeah, there is information embedded in there. But if I told you that it was from, you know, 2004 versus 2025, that's going to make a bigger difference to you, right? Like there's meaning that's communicated in there as far as, is this old? On the other hand, if you have a stable API and you don't make changes to it yearly and people are still using the 2019 version of your API, maybe that's fine. But it's kind of a double-edged sword. If you put the year in there and maybe which quarter or whatever, they might start asking, "Well, is this old? Should I be upgrading? This is five years old. Should I be making a change here?"
[00:24:15] Dave Adsit: That is one of the few forms of social pressure you can apply to your vast army of actual customers who are using your API. Like, "Why are we using an API that's 11 years out of date? Is there a new one?" "Oh, there's a hundred new ones." "Okay. Maybe we should upgrade." Okay. So there wouldn't be a hundred under the one a quarter, but there could be 45. There are 45 new versions since we used this one.
[00:24:41] Allan Stewart: And the nice thing about that is, though, is if you're not changing it very often, but you just take the time once, I don't know, once a quarter, once a year to add an additional route to the same handler that you already had. Like, that's super easy to do, which is part of the reason I prefer that over versioning endpoints individually. Because in addition to it being confusing, it's really easy to just have two routes that go to the same thing. It really is. And so you can ratchet up your marketing speak and be like, "Hey, it looks like you're four years out of date." Yeah, the API is actually exactly the same, but we can tell that you've been using this without thinking about changing it for a while. Right.
[00:25:27] Dave Adsit: So one of the things that comes up all the time is the idea that if we have an API, then we can just use it for all of these purposes. And as we've talked about these different categories, you can see that there are some problems that come if we use an API incorrectly. If we take our team or context API and we let our customers use it, that is going to break our ability to evolve our product because now we have to communicate with our customers when we want to change the API so that we can add new functionality. The same happens if we let our system users, if we treat a context or team API as though it were a system API. We get the same kind of behavior, maybe not as bad, but still we're going to impede our progress on delivering new value to customers. If we only use our customer API to build our product, that's going to, again, slow down our ability to build new functionality in the product. And so for me, it's really important that we take this concept of API and break it down into the purpose, the category, the type of API that we're actually shipping and avoid that false reuse. I've heard people say, "Hey, when we do this, when we build this integration between these two systems, let's make sure we do it with an API so that then we can give that API to customers later." Like, "You know what, that's actually, love where your head is around exposing functionality to customers. However, if we do that, it will impede our ability to evolve the system and especially the integration between these two components." So I think of that kind of improper API use or as a form of false reuse. We've talked before about how reuse is the false idol of the programmer. Like we pursue reuse before we've even gotten use out of something sometimes. And it's often building for reuse is a recipe for over-engineering something. So I try not to do that. I try to be clear on what type of API we're building so that we are not over-engineering and not wasting a bunch of time and not impeding our ability to create new value. It's all about creating new value for customers.
[00:27:46] Allan Stewart: Yeah, I think it's important to recognize the speed of change. What cadence do you observe change and create different APIs for that? Also, looking at purpose and audience can matter a lot too. So one of the things that we do at the company I'm working at right now is we, even though we have just a single team, we have a split in our context APIs. So we have separate endpoints for mobile, for our primary web app, and then we also have a customer portal web app. And these are three separate deployables, and we've intentionally broken them up. Even though some of them literally have controllers that use the exact, like, we will copy paste code from one to the other because it's exactly the same need. But we've separated it because that's not always true. Sometimes the mobile app needs a different method of aggregation of data. Same with the customer portal side. It doesn't, we need to restrict what kind of data comes back in the JSON payloads in a different way than is needed for the regular users of the primary web app to be able to do what they're doing. So even though all three of these APIs fall into the same bucket, right, the same API category, they're all public context as far as how they're categorized. It still was helpful to us to break them up. It gives us better visibility. It gives us better ability to build what is needed and be able to change it at the rate that we want to change it without worrying. It's like, "Oh, well, is that going to break the mobile app? No, it won't break the mobile app because they don't use this API at all."
[00:29:42] Dave Adsit: So when we talk about all of these different needs and purposes and customers, consumers for APIs, there will always be someone who says, "GraphQL solves all of this for us." Right? Because GraphQL lets every consumer decide what type of request and response they want. And we've talked about GraphQL before. I have identified what I think are some reasonable places to use GraphQL and some unreasonable places to use GraphQL. And I would say GraphQL is an unnecessary level of complexity if you are building an application or product on a single team because GraphQL allows you to decouple front-end from back-end. And the reason you want to decouple front-end from back-end is because you have aligned your teams around specialties. You've got your specialist front-end devs who don't want to talk to those back-end people. And you've got your specialist back-end people who don't want to talk to those front-end people. And so they create this layer that allows for lack of communication. And honestly, Honestly, what that does is it slows down your ability to deliver, slows down your system. Because even if you have GraphQL in place, you still have to expose the resolvers and you have to communicate and document all the resolvers that are available in the system. And you're running extra complexity as well. You've got to have some Apollo in there and you've got to have some tools in there that actually make GraphQL work. And so that it's not a good fit for a team or context level API.
[00:31:18] Allan Stewart: I think there's even an argument there that you're not acting as a team, right? Like you're, you're pushing what ought to be a team thing to a system level. Because you are even, even if you are team in name, if you are acting as sub teams that are separate and you're You're not communicating. Well, that's not a team.
[00:31:42] Dave Adsit: Correct. And that actually does bring up one context in which I believe GraphQL is the correct answer. That is where you have a single backend system and many, probably more than five, different frontend systems. For example, you're building Netflix and you've got a Samsung TV player, an Android phone player, an Apple TV player, an Apple phone player. You've got your own custom player that you've built and sold at trade shows. You've got the Roku one. You've got to make it work in Chrome, on Windows and Linux and Apple. And you've got to make Safari work. And you've got all of these different front ends and they all have the possibility of having slightly different needs and communication patterns, but they're all doing the exact same thing. And so you might have 15 different specialist front end teams building apps that all consume one API and have to consume it slightly differently. Maybe you need to have a lot of really small requests. We talked earlier about a RESTful API versus a fit for purpose API. Maybe you've got a lot of small requests versus maybe you, the system you're working on is optimized for larger payloads and fewer API calls. And so if you have that kind of a system, then you might need a tool like GraphQL to help bridge that gap. You would end up building something like that if you weren't just using GraphQL out of the box. And if you are building that kind of a system, then it's a good fit. Chances are you are not building that kind of a system. Most of us are not. And so for most of us, it's not a great fit because it doesn't meet an actual need we have. It's not a good fit. We talked about the unnecessary excess complexity that it introduces into a context or team API. It doesn't help when you're talking system to system either because you've got specific constraints and requirements around the system to system communication. And most of your customers are probably not sufficiently sophisticated to use a tool like GraphQL when something more like a RESTful API would make more sense for them.
[00:33:52] Allan Stewart: Another place I think is a good example is something big like GitHub, where this time it's a customer-facing thing, but you know your audience, right? You've got a bunch of programmers that are interacting with this and it's such a huge audience that you can't possibly know what the various needs are for all of the different kinds of apps. So it's almost the inverse of the Netflix example, right? Like with Netflix, it's the same, the same backend powering essentially the same experience, but across all these different devices that have different, different needs. But with GitHub, it's more like we have no idea all of the variety of things that people are going to be doing, but they're all pulling from our data. And so we're making it available in a very flexible, generic way, but they're also big enough that they can do, you know, caching and figure out how to solve the N plus one query problems and some of these access patterns and, and, and whatever else is needed to be able to host a big GraphQL instance like that, because, because you don't know how it's going to be used.
[00:35:04] Dave Adsit: Well, and that's where GraphQL evolved, right, is GraphQL was built by Facebook before they became Meta. And it was the social graph query language that they exposed to people who were building apps that needed arbitrary data about the social graph. And they didn't know how it was going to be consumed. And so they had to expose a lot of things. And we already know it's not a good idea to expose your database to your customers. You're not going to give somebody a connection string to your Postgres instance and let them just run wild in there. But by putting an API in front of it, by using a tool like GraphQL, you can create some level of constraint and some level of protection around the system. You're abstracting away the implementation of the system in the query language that's exposed.
[00:35:52] Allan Stewart: host. Yeah. But that's not a catch-all, though, right? So like the example that I gave earlier, we have a customer portal that needs a lot of the same kind of data. It's something that we control. It's the context API, but I can't allow that API to resolve certain data that I would allow this other consumer, even though it's all the same team. So if I were using GraphQL to solve this problem, I'd actually have to have two separate GraphQL instances or some separation there to allow, yes, this one can access some data, this one can't access some data, which adds some complexity that may or may not be warranted depending on the use case. Another example that I thought of as we're talking about, you know, kind of backing up up into the discussion of API categorization, we also have another split in the APIs that we use, just because sometimes you want something that is very bespoke, something that's very fit for purpose, and you don't necessarily have all the choices. So if you are going to create some web hooks that let you interact with another system, well, you might not have a choice. You can't go over to that third party company and say, Hey, I know you have this webhook subscription. Could you please make it so that it will talk in a particular language for me? Or, you know, I wish you wouldn't send me XML. I wish you would send me JSON. Like you might not get that choice. Or could you please send that data to me as a mutation of GraphQL? I was like, "Well, no, you get a POST that has some JSON in it." So there are cases like that where there are specific constraints where you might want to separate things out. So we've got separate endpoints that have a different kind of API structure for things like webhooks. And that's different from our Zapier integration. We've got a separate set of endpoints that are specifically for our Zapier integration because we know that it has a different set of constraints and it updates at a different timescale and things than the other parts of our system. And keeping those separate lets it run and continue to work without endangering that integration with other changes that are happening in other parts of the system.
[00:38:20] Dave Adsit: So as developers, we are consuming APIs and building APIs and delivering APIs all the time. And APIs have different characteristics and different needs. And hopefully through this discussion of categorization, it's helped you understand when you should use APIs of different types and how you should think about the constraints that come with the different consumers you can have for your APIs and make better choices about how to do system design.
Copyright © 2026 - Crafting Code Podcast