Skip to content

docs: Add ADR 0039 - Base API standards on IETF RFCs - #880

Merged
mike-gorman-bitwarden merged 8 commits into
mainfrom
docs/adr-0039-base-api-standards-on-ietf-rfcs
Oct 20, 2026
Merged

mike-gorman-bitwarden merged 8 commits into
mainfrom
docs/adr-0039-base-api-standards-on-ietf-rfcs

Conversation

@mike-gorman-bitwarden

@mike-gorman-bitwarden mike-gorman-bitwarden commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

🎟️ Tracking

Follow-up to ADR-0036 (#865).

📔 Objective

Adds ADR-0039, "Base API standards on IETF RFCs", with status Proposed. Decides what the service-to-service API standards are built on: our own standards, adopting an IETF RFC wherever one covers a topic and recording why wherever they don't.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Deploying contributing-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: de987a2
Status: ✅  Deploy successful!
Preview URL: https://c64e2c70.contributing-docs.pages.dev
Branch Preview URL: https://docs-adr-0039-base-api-stand.contributing-docs.pages.dev

View logs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment on lines +84 to +98

| | Own on RFCs | JSON:API | Hypermedia | OData | GraphQL | gRPC | AIP | Azure |
| ----------------------------------- | :---------: | :------: | :--------: | :---: | :-----: | :--: | :-: | :---: |
| Answers the common design questions | ⚠️ | ⚠️ | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ |
| Room for a version | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | ✅ |
| Contracts express required fields | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ✅ |
| Customer-friendly | ✅ | ✅ | ✅ | ⚠️ | ❌ | ❌ | ⚠️ | ✅ |
| Generated clients | ✅ | ✅ | ⚠️ | ⚠️ | ✅ | ✅ | ✅ | ✅ |
| Owner decides what can be queried | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ✅ | ⚠️ | ⚠️ |
| Works through customer proxies | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ⚠️ | ✅ |
| Works with HTTP infrastructure | ✅ | ✅ | ✅ | ✅ | ❌ | ⚠️ | ⚠️ | ✅ |
| Fits our stack | ✅ | ⚠️ | ✅ | ⚠️ | ✅ | ✅ | ⚠️ | ✅ |
| Streaming and push | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ⚠️ | ❌ |
| Compact wire format | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ⚠️ | ❌ |
| Published origin | ⚠️ | ✅ | ⚠️ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you expand on all the metrics? How does generated clients work for JSON:API? They specifically removed that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A definition of what each row's consideration or requirement means has been added below this table.

How does generated clients work for JSON:API? They specifically removed that.

I am not sure what you mean. Clients are generated from OpenAPI specs, typically via OpenAPI Generator or NSwag.

These client generators can generate clients from any OpenAPI spec, including ones that are based on JSON:API-style APIs. But I want to make it clear that this ADR does not propose we standardize on JSON:API. It says we may borrow from it where we see fit but nothing about this ADR says we will standardize on JSON:API or use anything from it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON:API library for c# removed support for OpenApi.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see what you're talking about now: JsonApiDotNetCore

That was basically a convenience library someone created for people that wanted to expose their data model directly as JSON:API style resources. That is not what we are doing and is not needed. And, as I mentioned before, this ADR does not endorse or reject any "idea" borrowed from the JSON:API spec.

Even if we do adopt many JSON:API conventions, at the end of the day, they are just C# classes/records with a particular shape that Swashbuckle/NSwag/Etc. handle just like they would any other C# types.

mike-gorman-bitwarden and others added 5 commits October 6, 2026 08:56
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@audreyality

audreyality commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

🤔 It seems to me that this ADR dismisses all established standards because none of them provide a comprehensive outlook on all possible operations that we can perform. The full sequence of ADRs attempt to span all of our services, looking for a "silver bullet". Since we cannot find a standard that satisfies the full conceivable set of operations, we're electing instead to create our own.

💭 Have we considered an option that classifies services according to their purpose? From there, we could adopt standards suited to specific purposes in their entirety.

For example, say we break down the categories as follows:

  • CRUD-style services that work on individual objects in a resource/RESTful style.
  • E2E encrypted services that are highly specialized, mostly opaque BLOBs.
  • Analytics services that process unencrypted records into reports.

The CRUD-style services might choose JSON:API; the E2E encrypted services might have a fully-specified custom protocol; the analytics services might use GraphQL. (Reminder: These are examples; I'm not proposing specific protocols. I'm proposing a different set of categories and follow-on ADRs that could evaluate the standards this ADR rejects on a case-by-case basis.)

The primary benefit of this approach is that we invest minimal effort in specifying common operations (CRUD, analytics), and concentrate our resources on the operations that are singular to our product (E2E encryption and zero-knowledge).

| | Own on RFCs | JSON:API | Hypermedia | OData | GraphQL | gRPC | AIP | Azure |
| ----------------------------------- | :---------: | :------: | :--------: | :---: | :-----: | :--: | :-: | :---: |
| Answers the common design questions | ⚠️ | ⚠️ | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ |
| Room for a version | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | ✅ |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GraphQL has a great article motivating their choice for versioning, I would argue their design pattern supports what we require in terms of versioning.

I would also argue they are very customer friendly, and great for BFF, which JSON:API is less great at.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this ADR is trying to establish is what we will base our standards on. Are you arguing that we should standardize on GraphQL for all of our service-to-service APIs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or are you just reacting to me awarding a ⚠️ symbol for GraphQL for API versioning? That came from their docs: https://graphql.org/learn/schema-design

While there’s nothing that prevents a GraphQL service from being versioned just like any other API, GraphQL takes a strong opinion on avoiding versioning by providing the tools for the continuous evolution of a GraphQL schema.

So, since the actively discourage API versioning, I gave them a warning sign instead of a checkmark.

@mike-gorman-bitwarden
mike-gorman-bitwarden marked this pull request as ready for review October 14, 2026 09:10
@mike-gorman-bitwarden
mike-gorman-bitwarden requested a review from a team as a code owner October 14, 2026 09:10
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Reviewed the new ADR-0039 (docs/architecture/adr/0039-base-api-standards-on-ietf-rfcs.md), which adopts our own API standards grounded in IETF RFCs as the foundation for the service-to-service API standards required by ADR-0036. The frontmatter follows the MADR structure used by the other ADRs, and the links to ADR-0036 and the ADR-0035 OpenAPI requirement resolve. The comparison table matches its row definitions and the rejection rationale, including the three-option claim in the decision outcome and the minimal APIs reference, which is consistent with ADR-0031. No new findings beyond the design discussion already underway in the existing threads.

@mike-gorman-bitwarden
mike-gorman-bitwarden enabled auto-merge (squash) October 20, 2026 14:34
@mike-gorman-bitwarden
mike-gorman-bitwarden merged commit 08b7ff5 into main Oct 20, 2026
15 checks passed
@mike-gorman-bitwarden
mike-gorman-bitwarden deleted the docs/adr-0039-base-api-standards-on-ietf-rfcs branch October 20, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants