</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 4: One Tag at a Time - API Design (with Pushback)

Executive Summary: This section designs the contract that Section 3's numbers will hit. Writes are per tag and idempotent, so concurrent editors can't erase each other's tags. Boards read tags in one batch call. The server hydrates and trims the tag page, so the client never receives a reference it may not see. Admin operations over millions of rows return a job. Tenant and user come only from the token, and every write asks the owning product first. We defend four choices under pushback: per-tag writes over list replacement, server hydration, an empty page over a 403, and names only in the add URL.

The interviewer hands over the marker: "Walk me through your API." Put the whole surface on the board first, then defend it line by line.

# Users, through the product UIs
PUT    /v1/content/{contentRef}/tags/{tagName}        add one tag (get-or-create + assign)
DELETE /v1/content/{contentRef}/tags/{tagId}          remove one tag
PUT    /v1/content/{contentRef}/tags                  replace the list (If-Match required)
GET    /v1/tags/{tagId}/content?product=&pageSize=25&cursor=   the tag page
GET    /v1/tags:suggest?prefix=&limit=10              autocomplete
GET    /v1/tags:popular?container=&limit=20           popular-tags panel

# Product backends
POST   /v1/content:batchGetTags                       tags for up to 200 items

# Tenant admins
POST   /v1/tags/{tagId}:rename                        sync
POST   /v1/tags/{tagId}:merge                         202 + jobId
DELETE /v1/tags/{tagId}                               202 + jobId
POST   /v1/content:bulkTag                            up to 1,000 refs, 202 + jobId

API surface by caller: users get per-tag PUT and DELETE, list replace, the hydrated tag page and suggest/popular; product backends get batchGetTags; tenant admins get synchronous rename and async merge, delete and bulkTag via bulk lane workers

Identity Lives in the Token, Nowhere Else

Look at what's missing from those paths: no tenant id and no user id. The API gateway verifies the token and passes (tenant, user) to the Tag API. Every handler scopes every query by that tenant, so no request shape can name another one.

Interviewer: "Content refs like jira:issue:10042 aren't globally unique. Two tenants can both have issue 10042."

You: "Right, and that's fine, because the ref is never looked up on its own. Bluefin's jira:issue:10042 is the row keyed (t-4471, jira:issue:10042). Another tenant's identical ref lands in a different key space. Isolation comes from the shape of the API, so there's no check anyone can forget."

The ref also uses the immutable id, not the issue key, because PAY-4312 gets a new key if it moves to another project.

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.