Speaker 1: Welcome to the deep dive. Today, we're jumping into something
Speaker 1: that powers so much of our digital world but often
Speaker 1: stays hidden, Web API design. Our main guide for this
Speaker 1: is the second edition of the Design of Web APIs
Speaker 1: by Arnoul Loray. It's described as taking you from well
Speaker 1: novice to pro in building APIs that work well, are
Speaker 1: easy to use, and importantly aren't a pain to deal with?
Speaker 1: So why should you care about this? Simple? Really a
Speaker 1: well designed API, it's like a secret startcut to making
Speaker 1: things work efficiently, giving users great experiences. A bad one, though,
Speaker 1: that's a recipe for frustration, crashes, slow apps, and just
Speaker 1: piling up technical problems nobody wants to deal with. Have
Speaker 1: you ever struggled with an apro website? Wondered why it
Speaker 1: was so slow, or maybe crash or just felt confusing?
Speaker 1: Often the root cause, buried deep down is poor API design.
Speaker 2: That's exactly right, and the challenge we're really going to
Speaker 2: unpack today is figuring out what goes into making an
Speaker 2: API that one does the right job, two is actually
Speaker 2: user friendly and works well with other systems. Three considers
Speaker 2: all the real world constraints like security and performance, and
Speaker 2: four is built using a process that keeps getting better.
Speaker 2: It's a skill that applies everywhere, whether it's an internal
Speaker 2: tool or a huge public platform.
Speaker 1: Okay, let's back up a bit. What exactly is a
Speaker 1: web API?
Speaker 2: Fundamentally, fundamentally, it's a software interface. Think of it as
Speaker 2: a way for different applications to talk to each other
Speaker 2: over a network, mostly using HTTP, the language of the web.
Speaker 1: So when my phone app gets new updates, that's an
Speaker 1: API talking to the back end precisely.
Speaker 2: Or when different server applications need to coordinate complex tasks
Speaker 2: behind the scenes, APIs make that communication possible, and they're
Speaker 2: not just single channels. One API can offer many different
Speaker 2: operations and many different apps can use that same API.
Speaker 2: We should probably also mention the types private for internal use,
Speaker 2: partner for specific collaborators, and public APIs for well everyone
Speaker 2: and a key thing. Even private APIs might still be
Speaker 2: accessible from the Internet. So design and security or just
Speaker 2: as crucial there.
Speaker 1: Right, which brings us square to why good design is
Speaker 1: so critical. Often the best way to see that is
Speaker 1: to look at the pain caused by bad design. The
Speaker 1: book mentions things like cryptic or inconsistent naming, poor data organization,
Speaker 1: maybe missing data or operations we've all been there, right,
Speaker 1: I definitely remember hours spent trying to figure out why
Speaker 1: a call failed, only getting back a totally unhelpful bad
Speaker 1: request error. Just maddening.
Speaker 2: Oh. Absolutely, it's a classic developer nightmare. Laurie uses this
Speaker 2: brilliant analogy in the book The Kitchen Radar. Imagine a microwave,
Speaker 2: but instead of normal controls, it just has one button
Speaker 2: bag and you have to hold it down to heat things,
Speaker 2: figuring out the timing yourself.
Speaker 1: Huh, so you have to become a magnetron expert just
Speaker 1: to warm up coffee exactly.
Speaker 2: It sounds absurd, but it perfectly mirrors how some poorly
Speaker 2: designed APIs force developers to understand obscure internal details, and
Speaker 2: the impact is huge. Developers write fragile, complex code, end
Speaker 2: users get crashes, confusing errors, maybe workflows that make.
Speaker 1: No sense, which leads to frustration, maybe canceling subscriptions or
Speaker 1: just switching to a competitor.
Speaker 2: Right, and for the company providing the API, it means
Speaker 2: rising technical debt, wasted engineer time, production problems, security risks,
Speaker 2: even lost revenue. It's bad for everyone.
Speaker 1: Okay, So if the kitchen radar is what we want
Speaker 1: to avoid, how do we actually build something good? How
Speaker 1: does this design process fit into actually building software?
Speaker 2: Well? API design sits in that crucial space between figuring
Speaker 2: out what's needed and actually starting to write the code.
Speaker 2: It's a process. You move through stages like identify API capabilities,
Speaker 2: then you design the programming interface. Then you need to
Speaker 2: describe it clearly, and finally enrich those design documents.
Speaker 1: Okay, and the book breaks this down conceptually into layers.
Speaker 2: Yeah, four conceptual layers, each tackling a different aspect of
Speaker 2: the problem. The helpful way to think about it. First,
Speaker 2: a versatile API design that does the right job. This
Speaker 2: is about meeting the real user needs, hiding the messy
Speaker 2: internal stuff, and making it usable in ways you might
Speaker 2: not even anticipate yet. Think about a so network API.
Speaker 2: Maybe today it serves the mobile and web apps, but
Speaker 2: a well designed versatile one could potentially power a smart
Speaker 2: fridge integration tomorrow without needing a rewrite.
Speaker 1: Interesting future proofing, almost what's next.
Speaker 2: Second layer, an API design that is user friendly and interoperable,
Speaker 2: making it easy to understand, easy to use, and ensuring
Speaker 2: it plays nicely with other systems. Common sense, but crucial
Speaker 2: makes sense. Third third, an API design that considers constraints.
Speaker 2: This is where you really integrate things like security performance,
Speaker 2: the specific context it operates in, and how you'll handle
Speaker 2: future changes. And the final layer, finally, a reasoned and
Speaker 2: continuously improving API design process. This is about how you
Speaker 2: make decisions consistently based on good principles and always looking
Speaker 2: for ways to improve.
Speaker 1: Okay, let's dive into that first layer. Then identifying capabilities.
Speaker 1: Where do you even start?
Speaker 2: You start by analyzing the user needs. This often begins
Speaker 2: pretty vague, like we need a social network, you.
Speaker 1: Know, right, very high level exactly.
Speaker 2: But you need to quickly get more specific. What does
Speaker 2: that actually mean for users? Maybe it's allow users to
Speaker 2: tag friends in a photo. The key is expressing these
Speaker 2: needs in plane language first, something everyone involved can understand.
Speaker 1: So how do you break those big needs down systematically?
Speaker 2: Decomposition is key breaking down those use cases into small,
Speaker 2: manageable steps. The book introduces a tool called the API
Speaker 2: Capabilities Canvas for this. You work through it twice. Essentially, First,
Speaker 2: you map out the happy path, the way things should
Speaker 2: work ideally, the normal flow right. Then you go back
Speaker 2: and figure out all the alternative paths. There are edge cases,
Speaker 2: and importantly, the failure scenarios what happens when things go wrong,
Speaker 2: and doing this often reveals overlaps, like the step upload
Speaker 2: of photo might be needed for sharing a status and
Speaker 2: for changing your profile picture, same underlying capability, different context.
Speaker 1: Okay, so you've identified these capabilities, how does that translate
Speaker 1: into the actual interface a developer interact with the programming interface?
Speaker 2: Those capabilities generally map onto two core concepts, resources and actions.
Speaker 2: A resource is like a now a high level concept
Speaker 2: like product, user, order and actions are the verbs what
Speaker 2: you can do to those resources get product, create, order, update,
Speaker 2: user search products.
Speaker 1: And how are those represented in a typical web API
Speaker 1: using HTTP.
Speaker 2: That's where the standard AGTP methods come in. Get to retrieve,
Speaker 2: post to create, put to replace, patch to partially update,
Speaker 2: and delete to remove. You combine these methods with resource paths,
Speaker 2: which are like addresses for your resources products for the
Speaker 2: collection products one, two, three for a specific one.
Speaker 1: So the path structure shows relationships like users, four, five, six,
Speaker 1: orders exactly.
Speaker 2: It describes hierarchy. But, and this is crucial, the paths
Speaker 2: should not directly mirror how your data is stored internally.
Speaker 2: You want to hide the provider's perspective and focus on
Speaker 2: the consumer's needs.
Speaker 1: That keeps it flexible, right decoupling. Now, when a developer
Speaker 1: makes a request, where does the input data actually go?
Speaker 2: Good question? There are standard places within an HTTPU request.
Speaker 2: Path parameters are usually for identifiers like that product's one
Speaker 2: twenty three. The one to twenty three is a path parameter.
Speaker 1: Okay, it makes sense.
Speaker 2: Query parameters live after the question mark in the URL.
Speaker 2: They're great for things that modify the request like filter, status, published, sorting,
Speaker 2: or pagination in any ear, you don't want to force
Speaker 2: these into the path as they're often optional.
Speaker 1: Got it? What else?
Speaker 2: Headers carry metadata about the request itself, things like authentication tokens,
Speaker 2: authorization bearer, or specifying the content type being sent, content type, dot, application, adjacent.
Speaker 1: And the main data for creating something new.
Speaker 2: That usually goes in the request body, especially for post
Speaker 2: put and patthch requests, where you're sending a representation of
Speaker 2: the resource.
Speaker 1: Okay, so that's input. What about the output? How does
Speaker 1: the API tell the consumer what happened?
Speaker 2: Primarily through HTDP status codes, those familiar three digit.
Speaker 1: Numbers like two hundred to ok or four or four
Speaker 1: not found exactly.
Speaker 2: They fall into classes two XX means success. Four x
Speaker 2: means the client messed up, bad input, not authorized, et cetera.
Speaker 2: Five xx means something went wrong on the server side.
Speaker 2: Common success codes include two oh one created when you
Speaker 2: successfully make a new resource, or two oho four to
Speaker 2: no content after a successful deletion where there's nothing to return,
Speaker 2: and errors four hundred to bout amount. Bad request is
Speaker 2: common for invalid input, four to one, unauthorized, four oh
Speaker 2: three forbidden, four hundred for four and not found. They
Speaker 2: all signal specific client side issues. Crucially, successful responses often
Speaker 2: return data in the response body, and for creations a
Speaker 2: two oh one you should usually include a location header
Speaker 2: pointing to the URL of the newly created resource.
Speaker 1: Makes sense, Let's shift to the data itself. How do
Speaker 1: you actually define the structure of the information being passed
Speaker 1: back and forth.
Speaker 2: That's where data modeling comes in, usually using Jason's schema
Speaker 2: within an open API specification. It gives you a formal
Speaker 2: way to describe the data structure, types, constraints, everything.
Speaker 1: And the book suggests a particular approach.
Speaker 2: Yeah. It emphasizes the idea of starting with a theore,
Speaker 2: medical or complete resource model. Think of your product resource
Speaker 2: to find everything it could possibly contain all the details
Speaker 2: the maximal view. Right then that complete model becomes the
Speaker 2: source for deriving other more specific models you'll actually use
Speaker 2: in the API, like summarize models for when you return
Speaker 2: a list. You don't need every detail to summary minimal
Speaker 2: models that might just contain the ID maybe for linking
Speaker 2: between resources. Creation models for PST requests often a subset
Speaker 2: of the full model only the fields needed to create it.
Speaker 2: Same for put replacement.
Speaker 1: And PCCh for updates.
Speaker 2: Exactly, modification models for PTH, where typically all fields are
Speaker 2: optional because you're only changing some things. This approach brings
Speaker 2: a lot of consistency. You're not defining similar structures over
Speaker 2: and over again.
Speaker 1: That leads nicely into data user friendliness. It's not just
Speaker 1: about structure, but the content of the data, right.
Speaker 2: Absolutely, it's about selecting data that's genuinely relevant and helpful
Speaker 2: to the consumer, not just dumping everything from your database.
Speaker 2: The idea here is providing supporting data or even process data.
Speaker 1: What's an example of that.
Speaker 2: The book gives a great banking API example. Instead of
Speaker 2: just giving the raw count balance and the overdraft limit
Speaker 2: and forcing the consumer to calculate if a purchase is possible.
Speaker 1: You could provide a calculated safe to spend amount exactly
Speaker 1: that directly answers the user's likely question, reduces the chance
Speaker 1: of errors on their side, and makes the API much
Speaker 1: easier to use.
Speaker 2: It's about anticipating needs.
Speaker 1: That's smart. What else contributes to user friendly data?
Speaker 2: Using well known or standard identifiers whenever possible, Like use
Speaker 2: an IBAND for a bank account if that's the standard.
Speaker 2: Don't just expose your internal database ID.
Speaker 1: Makes sense less look up needed right, and use.
Speaker 2: Human readable codes instead of account type one. Use account
Speaker 2: type checking. It's immediately understandable, and of course, be super
Speaker 2: consistent with your atomic data types and formats. Always use
Speaker 2: ISO eighty six to ZHO one for dates and times
Speaker 2: for example, no surprises.
Speaker 1: Okay, And how about organizing the data within a response?
Speaker 1: Structuring it well?
Speaker 2: Good structure is key. Use objects to group related feels together,
Speaker 2: like instead of overdraft limit and overdraft, use floating around
Speaker 2: group them in an overdraft facility.
Speaker 1: Object keeps things tidy.
Speaker 2: Yeah, and use a raise for lists of similar items,
Speaker 2: like a balance's array if an account can have multiple
Speaker 2: currency balances. But there's a big caution here. Avoid embedding
Speaker 2: large lists directly within a main resource response, especially if
Speaker 2: those lists might need filtering or pagination.
Speaker 1: Like putting all of a user's transaction history inside the
Speaker 1: main user object exactly.
Speaker 2: That's usually a bad idea. If you need to get transactions,
Speaker 2: provide a dedicated operation like users one, two, three transactions
Speaker 2: that supports pagination and filtering properly. Don't overload the primary resource.
Speaker 1: That makes a lot of sense for performance too.
Speaker 2: Absolutely, and the golden rule overarting all of this data
Speaker 2: design is consistency, naming, conventions, data types. How you structure
Speaker 2: objects in a raise keep it consistent across the entire API.
Speaker 2: That predictability makes the API dramatically easier and faster for
Speaker 2: developers to learn and use.
Speaker 1: Right, Okay, let's pivot to constraints. Starting with a big
Speaker 1: one security, How does API designed influence security massively?
Speaker 2: Security isn't something you bolt on at the end. It
Speaker 2: needs to be baked into the design choices you make
Speaker 2: from the start. Your design is part of your security posture.
Speaker 1: So how do you design for security?
Speaker 2: A fundamental principle is minimizing the API surface area. Only
Speaker 2: expose the operations and the data that are absolutely necessary.
Speaker 2: Really challenge requests for sensitive data. Do we really need
Speaker 2: to expose the user's exec GPS coordinates or their phone number?
Speaker 1: If so, why and if you do need it.
Speaker 2: Maybe can transform it, perhaps return a city or region
Speaker 2: instead of precise coordinates, or maybe split very sensitive operations
Speaker 2: off into a separate API that has much tighter access controls.
Speaker 2: Less exposure means less risk.
Speaker 1: Speaking of access control, how does that work in API design?
Speaker 1: You mentioned scopes earlier.
Speaker 2: Yes, scopes are a common mechanism for authorization. They define permissions.
Speaker 2: You might have a red profile scope and a separate
Speaker 2: update profile scope, or maybe a transfer money scope.
Speaker 1: So the API consumer requests certain scopes and the API
Speaker 1: checks if they have them before allowing an operation.
Speaker 2: Exactly, and scopes can be defined that different levels of
Speaker 2: granularity per operation, per resource type, maybe even based on
Speaker 2: the specific user role or the application making the call.
Speaker 2: Depends on your security requirements.
Speaker 1: Okay, what about protecting the data itself? Data integrity?
Speaker 2: Several design aspects contribute here. First, using HTTP methods correctly
Speaker 2: get should be safe, no side effects. Put in delete
Speaker 2: should be idempatant. Running them multiple times as the same
Speaker 2: effect as running them.
Speaker 1: Once prevents accidental double charges or double deletions. If a
Speaker 1: request is retried precisely.
Speaker 2: You can also prevent malicious or accidental request replays by
Speaker 2: requiring an adempotency key header. For non adempitent operations like PFOST,
Speaker 2: the server uses this key to ensure it only processes
Speaker 2: the request once AH and for updates. Condition updates are vital.
Speaker 2: Imagine two users trying to update the same customer record
Speaker 2: at the same time.
Speaker 1: One might overwrite the other's changes without realizing it right.
Speaker 2: Using E tag hitters, which represent the version of the
Speaker 2: resource and if match hitters, which say only perform this
Speaker 2: update if the E tag matches what I last saw
Speaker 2: prevents this lost update problem.
Speaker 1: Got it? That seems really important for data consistency. What
Speaker 1: about handling errors securely?
Speaker 2: Yes, secure air handling is crucial. You need to give feedback,
Speaker 2: but not too much information that could help an attacker.
Speaker 2: Use standard machine readable error formats like problem details for httpapis.
Speaker 2: This provides structure type, title, status, detail, instant It.
Speaker 1: Avoid generic unhelpful messages like just error definitely.
Speaker 2: But also return all validation errors at once if possible.
Speaker 2: Don't make the consumer fix one thing, resubmit find another error.
Speaker 2: Fix that. It's incredibly frustrating.
Speaker 1: Yeah, that back and forth is terrible. Any other security
Speaker 1: pitfalls and.
Speaker 2: Design one big one. Sensitive data in URLs. Even with
Speaker 2: HTTPS URLs, paths and query parameters can leak. They might
Speaker 2: end up in browser history, server logs, referra headers, So.
Speaker 1: Putting a password or credit card number in a query
Speaker 1: parameter is a definite no.
Speaker 2: No absolutely for anything sensitive, especially if it's being used
Speaker 2: for searching or filtering. Strongly, consider using a post request
Speaker 2: and putting these sensitive data securely in the request body instead.
Speaker 1: Good tip. Okay, let's switch from security to another key constraint. Efficiency.
Speaker 1: Why is this so important?
Speaker 2: Efficiency benefits everyone? For consumers, it means faster apps, less
Speaker 2: battery drain on mobile, lower data usage. For the API provider,
Speaker 2: it means lower server costs, less strain on infrastructure, better scalability.
Speaker 2: Small efficiencies can save a lot of money at.
Speaker 1: Scale, So how do you design for efficiency? Caching seems
Speaker 1: like an obvious one.
Speaker 2: Cashing is huge. Using standard HTTP caching headers like cash
Speaker 2: control tells downstream caches, browsers, CDNs proxies how long they
Speaker 2: can use a response without.
Speaker 1: Asking again, saves bandwidth and reduces load massively.
Speaker 2: And even better is using conditional requests with ETag and
Speaker 2: if none match, the client sends the ETag it has
Speaker 2: for a resource. If the resource hasn't changed on the server,
Speaker 2: the server just replies with a tiny three to four
Speaker 2: not modified response without sending the data. Again super efficient.
Speaker 1: Nice. What about reducing the end of data sent in
Speaker 1: the first place?
Speaker 2: Several techniques we mentioned Resource model selection earlier let consumers
Speaker 2: ask for a summarized view if they don't need all
Speaker 2: the details. Field selection is another, allowing consumers to explicitly
Speaker 2: request only the fields they need, like dot field's name. Balance,
Speaker 2: Why send data they're just going to ignore?
Speaker 1: Good point.
Speaker 2: Also look for redundant data. If the same piece of
Speaker 2: information appears in many different responses, maybe centralize it in
Speaker 2: its own resource or operation, and definitely prefer partial updates
Speaker 2: using PTCH over full replacements with pet when possible, Sending
Speaker 2: only the changed fields is much more efficient than sending
Speaker 2: the entire resource representation.
Speaker 1: Again right, the book mentioned two types of PTCH.
Speaker 2: Yes, Jason merge patch is simpler, basically merging the provided
Speaker 2: JSON into the existing resource. Jason patch is more powerful,
Speaker 2: using explicit operations like ad remove, replace targeted at specific
Speaker 2: parts of the Jason document. It's better for complex updates,
Speaker 2: especially involving a raise.
Speaker 1: Okay, what about handling large lists of items efficiently?
Speaker 2: Pagination is essential, don't try to return thousands of items
Speaker 2: in one go. Break it into pages.
Speaker 1: Index based or cursor based.
Speaker 2: Both have pros and cons Cursor based is generally more
Speaker 2: robust against data changing while you're paginating. But the critical
Speaker 2: design decision here is a default page size. The book
Speaker 2: warns against huge defaults like ten thousand that can hammer
Speaker 2: your database and the network. Choose a sensible default, maybe
Speaker 2: twenty fifty or one hundred, and let consumers request more
Speaker 2: if they really need it.
Speaker 1: Sensible advice any other efficiency boosters.
Speaker 2: Bulk operations can be great. Instead of making one hundred
Speaker 2: separate API calls to create one hundred acas ounce, allow
Speaker 2: a consumer to send a single request with all one
Speaker 2: hundred much less network overhead.
Speaker 1: But how do you handle errors in bulk operations? If
Speaker 1: one fails?
Speaker 2: That's the key design choice. Is it all or nothing
Speaker 2: one failure fails the whole batch, or do you process
Speaker 2: each one individually and return a mixed result. The each
Speaker 2: TTP two O seven multi status response code is often
Speaker 2: used for mixed results indicating success or failure for each
Speaker 2: item in the batch.
Speaker 1: Okay, and finally managing usage.
Speaker 2: Right rate limiting. You need to control how frequently consumers
Speaker 2: can call your API to protect your infrastructure from overload,
Speaker 2: whether accidental or malicious, and crucially be transparent about it.
Speaker 2: Use standard headers like rate limit limit, rate limit, remaining,
Speaker 2: rate limit reset, or the older X rate limit versions
Speaker 2: so consumers know the rules and can adjust their behavior.
Speaker 1: Makes sense. Protect yourself, but let users know the limits exactly.
Speaker 2: It's about fairness and stability. Now, beyond security and efficiency,
Speaker 2: good API design has a consider the broader context that
Speaker 2: operates in What are the specific needs or constraints of
Speaker 2: this particular situation.
Speaker 1: Can you give some examples of these contextual constraints?
Speaker 2: Sure? Think about file handling. If you need to upload
Speaker 2: a file along with some metadata, multipart form data is
Speaker 2: a standard way or maybe Base sixty four encoding for
Speaker 2: small files embedded in JSON, though that increases size.
Speaker 1: What about really big files, uploading videos or something.
Speaker 2: Yeah, for large files, hitting your main API gateway might
Speaker 2: not be efficient or even possible due to size limits.
Speaker 2: A common pattern is to use sign URLs your API
Speaker 2: generates a temporary, secure URL, maybe pointing to cloud storage
Speaker 2: like S three gives it to the client, and the
Speaker 2: client uploads or downloads directly from storage by passing your
Speaker 2: main API infrastructure for the bulk transfer.
Speaker 1: Ah, that's clever, offloading the heavy lifting. What else?
Speaker 2: Event notification Sometimes the consumer needs to know when something
Speaker 2: happens immediately without constantly asking the API anything new.
Speaker 1: Yet that's pulling right can be inefficient.
Speaker 2: Very The alternative is web hoooks. The consumer provides a URL,
Speaker 2: and your API calls their URL proactively whenever is specific
Speaker 2: event occurs, like a new order, place to transaction completed.
Speaker 2: Standard formats like cloud vents help make these web hoook
Speaker 2: payloads consistent and understandable.
Speaker 1: So the information flows the other way when needed. What
Speaker 1: about tasks that just take a long time.
Speaker 2: Long running operations, Yeah, like starting a complex data analysis
Speaker 2: job or a simulation. The initial API call might return immediately,
Speaker 2: maybe for the status urrol. Then the client has two options,
Speaker 2: polling checking that status URL periodically until the job is done, or,
Speaker 2: if supported, providing a callback URL similar to a webhook,
Speaker 2: where your API will notify them once the long operation
Speaker 2: is complete.
Speaker 1: Choosing the right pattern depends on the use case, I
Speaker 1: guess absolutely.
Speaker 2: And this idea of choosing the right pattern extends to
Speaker 2: the type of API itself. Rest Over HTTP is the
Speaker 2: default for many webapis, and it's great for request response
Speaker 2: interactions with resources, but it's not the only tool.
Speaker 1: When might you choose something else.
Speaker 2: If you need to stream data continuously from server to client,
Speaker 2: maybe e Server sent Events SSE is better for real
Speaker 2: time two way communication like a chat app. Web sockets
Speaker 2: might be the answer. If you have mobile apps needing
Speaker 2: very specific, flexible data combinations to avoid overfetching. Maybe graphic
Speaker 2: cool makes senses a back end for front.
Speaker 1: End layer and for internal micro services.
Speaker 2: gRPC is often chosen there for its high performance and
Speaker 2: strong typing, especially in polyglot environments. The point is understand
Speaker 2: the need first, then choose the appropriate API style or technology.
Speaker 2: Don't just default to rest for everything.
Speaker 1: That leads to a really important question. APIs aren't static.
Speaker 1: They need to change. How do you manage modifications and versioning?
Speaker 2: This is critical for maintaining stability for your consumers. The
Speaker 2: first step is understanding the difference between backward compatible changes
Speaker 2: and breaking changes.
Speaker 1: What's the difference?
Speaker 2: Backward compatible changes don't break existing clients. Adding a new
Speaker 2: optional field to a response, for example, or adding a
Speaker 2: new value to an existing enumeration, Consumers who don't know
Speaker 2: about the new stuff.
Speaker 1: Just ignore it, okay, safe changes right.
Speaker 2: Breaking changes, on the other hand, will break existing clients
Speaker 2: if they're not updated. Renaming a required field, changing a
Speaker 2: field's data type like from a string to a number,
Speaker 2: removing an operation entirely, making an optional field required. These
Speaker 2: all require consumers to.
Speaker 1: Adapt, So how do you manage those breaking changes? That's
Speaker 1: where versioning comes in exactly.
Speaker 2: You need a versioning strategy. Semantic versioning like one point
Speaker 2: oh one point one two point zero is common, where
Speaker 2: the major version number the two point zero increments only
Speaker 2: when you introduce braking changes. Minor increments are for backward
Speaker 2: compatible additions. Some use deep based versioning like twenty twenty
Speaker 2: five oh eight twenty, which can be simpler if you
Speaker 2: release very frequently, but makes it harder to know what
Speaker 2: change without reading talks.
Speaker 1: And how is the version usually specified in the API call.
Speaker 2: The most common way is path level versioning. You stick
Speaker 2: the major version right in the URL path like V
Speaker 2: one products or VW two products. It's simple, explicit, and
Speaker 2: easy for routing and casing. Other methods exist head query prams,
Speaker 2: but path is very popular.
Speaker 1: To minimize the need for breaking changes, can you design
Speaker 1: for extensibility from the start?
Speaker 2: Absolutely, that's key. Make choices that leave room for future evolution.
Speaker 2: For instance, always return chase on objects as the top
Speaker 2: level in your response bodies. Even if you only have
Speaker 2: one field right now, it's easy to add more fields
Speaker 2: later without breaking things. Good tip use a raise of objects,
Speaker 2: not just a rays of simple strings or numbers. If
Speaker 2: you think those items might need more associated data later.
Speaker 2: Prefer numerations like status active over simple booleans is active true.
Speaker 2: It's easier to add more statuses later pending inactive than
Speaker 2: to change a booleon. These small things add up to
Speaker 2: make future changes much less painful.
Speaker 1: Okay, we've covered the what and how of design? What
Speaker 1: about the final layer, the design process itself, making it
Speaker 1: reasoned and improving.
Speaker 2: Right, This is about ensuring your design decisions aren't just
Speaker 2: random or based on gut feeling. You need confident decision making.
Speaker 2: That confidence comes from relying on trusted sources. Maybe it's
Speaker 2: your own well defined internal API design guidelines. Maybe it's
Speaker 2: established external standards like the HTTPIE speck itself, or things
Speaker 2: like problem details, cloud events, maybe industry specific standards like
Speaker 2: ISO twenty twenty two in.
Speaker 1: Finance, So standing on the shoulders of giants essentially.
Speaker 2: Kind of yeah, and importantly document significant decisions, especially when
Speaker 2: you deviate from a standard or make a tricky trade off.
Speaker 2: Architectural decision records ADRs are a great way to capture
Speaker 2: the y behind a choice.
Speaker 1: You mentioned API design guidelines. How valuable are those?
Speaker 2: Immensely valuable. Think of them as your teams or organization's
Speaker 2: cookbook for APIs. They provide agreed upon recipes for common patterns,
Speaker 2: how we do CRI, how we handle searching and filtering,
Speaker 2: standard file upload methods, how we structure errors. Having these
Speaker 2: guidelines saves countless hours arguing about the same things over
Speaker 2: and over again on different projects. It promotes consistency.
Speaker 1: Can you automate the enforcement of these guidelines?
Speaker 2: Yes, that's where automated guidelines or API line come in.
Speaker 2: Tools like Spectral are designed for this. You can figure
Speaker 2: the linter with your rules. Properties must be CamelCase, pagination
Speaker 2: must use these specific parameters, air responses must follow the
Speaker 2: problem detail structure, etc. Then the linter analyzes your open
Speaker 2: API definition file and points out any violations.
Speaker 1: Giving feedback directly in the design phase exactly.
Speaker 2: It gives clear feedback, errors, warnings, info hints, helping designers
Speaker 2: stick to the standards and catch potential issues way before
Speaker 2: coding even starts. It's a huge boost for quality and consistency.
Speaker 1: Finally, the open API document itself the description of the API.
Speaker 1: Any tips for optimizing that definitely.
Speaker 2: Make it easy to read and maintain. Use ref Jason
Speaker 2: pointers heavily to reuse common components like schemas, parameters, standard responses.
Speaker 2: Don't repeat yourself.
Speaker 1: Define it once, reuse it everywhere right, and.
Speaker 2: Enrich it with details. Use JSON schema keywords precisely specify
Speaker 2: min length, max length, pattern regular expressions for validation enum
Speaker 2: allowed value, use default values. The more precise the definition,
Speaker 2: the better, and examples Examples are crucial. Include realistic examples
Speaker 2: for request bodies, response bodies, parameters. They make the API
Speaker 2: much easier to understand and test for consumers. Don't skimp
Speaker 2: on examples, and as a final point on process, consider
Speaker 2: API mocking or prototyping. Early on tools can generate a
Speaker 2: mock server based on your opening API.
Speaker 1: File so you can interact with it before it's built.
Speaker 2: Yeah. Hey, let's you and potential consumers try out the design,
Speaker 2: see if it feels right, catch awka parts, and iterate
Speaker 2: much faster than if you wait until the code is written. Wow.
Speaker 1: Okay, so we've really journeyed through a lot there. We've
Speaker 1: taken you, the listener, through these layers, from figuring out
Speaker 1: what the API needs to do, designing that interface, modeling
Speaker 1: the beta, carefully building insecurity and efficiency, handling context, managing
Speaker 1: change with versioning, and finally refining the whole process with
Speaker 1: guidelines and tools.
Speaker 2: Yeah, it really underscores the good API design isn't just
Speaker 2: a single task. It's an ongoing craft. It's this constant
Speaker 2: balancing act between what users need, what's technically feasible and constrained,
Speaker 2: and how things might evolve. It's less about just banging
Speaker 2: out code and much more about deliberately crafting these interfaces
Speaker 2: that enable smooth, effective digital experiences for everyone involved.
Speaker 1: So here's a final thought to leave you with as
Speaker 1: you go about your day thinking about the systems you
Speaker 1: build or use. What seemingly small API design choice being
Speaker 1: made today might turn out to be a major roadblock,
Speaker 1: or perhaps a brilliant enabler for your users and systems
Speaker 1: down the road,