-
-
Notifications
You must be signed in to change notification settings - Fork 38
docs: cover custom API handlers and server adapters for v3 #508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
docs: cover custom API handlers and server adapters for v3 #508
Conversation
|
@mwillbanks is attempting to deploy a commit to the ZenStack Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds new documentation for building custom server adapters and custom API handlers, extends REST and RPC handler docs with customization examples, and updates the server-adapter catalog to include a Custom adapter entry. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as Client (HTTP)
participant Adapter as Custom Server Adapter
participant Handler as ApiHandler (Rest/RPC)
participant DB as ZenStack Client / DB
Client->>Adapter: Incoming request (method, path, headers, body)
Adapter->>Handler: map request -> ApiHandler.processRequest / requestContext
alt success
Handler->>DB: resolve client / execute query
DB-->>Handler: query result
Handler-->>Adapter: Response {status, headers, body}
else error
Handler-->>Adapter: error payload / logInternalError
end
Adapter-->>Client: send HTTP response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (3)
🔇 Additional comments (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
versioned_docs/version-3.x/service/api-handler/custom.md (3)
12-12: Hyphenate compound adjective "brand-new".The phrase "author brand new handlers" should use a hyphenated form since it's a compound adjective modifying "handlers".
- override parts of the REST or RPC pipeline (filtering, serialization, validation, error handling, and more); - wrap the default handlers with extra behavior (multi-tenancy, telemetry, custom logging); - implement a handler from scratch while still benefiting from ZenStack's schema and serialization helpers.Apply this correction:
- override parts of the REST or RPC pipeline (filtering, serialization, validation, error handling, and more); - wrap the default handlers with extra behavior (multi-tenancy, telemetry, custom logging); - implement a brand-new handler from scratch while still benefiting from ZenStack's schema and serialization helpers.
82-82: Simplify "Refer back to" → "See".The phrase "Refer back to" is unnecessarily wordy. Use a more concise alternative.
- Refer back to the [RESTful API Handler](./rest) page for the canonical behavior and extension points. + See the [RESTful API Handler](./rest) page for canonical behavior and extension points.
119-119: Simplify "Refer back to" → "See".The phrase "Refer back to" is unnecessarily wordy. Use a more concise alternative.
- Refer back to the [RPC API Handler](./rpc) page for the canonical behavior and endpoint matrix. + See the [RPC API Handler](./rpc) page for canonical behavior and endpoint matrix.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
versioned_docs/version-3.x/reference/server-adapters/custom.mdx(1 hunks)versioned_docs/version-3.x/service/api-handler/custom.md(1 hunks)versioned_docs/version-3.x/service/api-handler/rest.md(1 hunks)versioned_docs/version-3.x/service/api-handler/rpc.md(1 hunks)versioned_docs/version-3.x/service/server-adapter.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
versioned_docs/version-3.x/service/api-handler/custom.md
[grammar] ~12-~12: Use a hyphen to join words.
Context: ...an tailor their behavior or author brand new handlers without leaving TypeScript....
(QB_NEW_EN_HYPHEN)
[style] ~82-~82: ‘Refer back’ might be wordy. Consider a shorter alternative.
Context: ...Ids` to expose bespoke query features. Refer back to the RESTful API Handler pa...
(EN_WORDINESS_PREMIUM_REFER_BACK)
[style] ~119-~119: ‘Refer back’ might be wordy. Consider a shorter alternative.
Context: ...subset of models to a specific client. Refer back to the RPC API Handler page fo...
(EN_WORDINESS_PREMIUM_REFER_BACK)
🔇 Additional comments (9)
versioned_docs/version-3.x/service/api-handler/rest.md (1)
967-1008: Well-structured customization guide with clear example.The new section effectively demonstrates handler extension through a practical example. The forward reference to the comprehensive Custom API Handler guide at line 1008 provides good progression for readers wanting deeper guidance.
versioned_docs/version-3.x/service/api-handler/custom.md (3)
35-75: REST handler extension example is clear and practical.The PublishedOnlyRestHandler demonstrates the intended pattern well: override a single
protectedmethod and delegate the rest to the base class. The example correctly shows how to merge custom filters with query-parsed filters.
85-120: RPC handler extension example demonstrates unmarshaling customization effectively.The Base64QueryHandler shows how to intercept and transform query encoding before delegating to superjson deserialization. The note about Node's Buffer dependency and fallback suggestion for edge runtimes is pragmatic.
122-155: Handler-from-scratch implementation is instructive and minimal.The HealthcheckHandler example effectively demonstrates the
ApiHandlercontract and the importance of callingregisterCustomSerializers()once. The minimal implementation is approachable while still being complete.versioned_docs/version-3.x/reference/server-adapters/custom.mdx (3)
9-11: Effective motivation for when to build a custom adapter.The "When to build one" section clearly articulates the scenario and emphasizes code reuse through shared utilities, which is a good incentive.
30-98: Minimal Node HTTP adapter is a complete, instructive example.The
createNodeAdapterfactory function demonstrates all essential pieces: URL parsing, client resolution with error handling, RequestContext construction, handler delegation, and response serialization. The error paths uselogInternalErrorconsistently with built-in adapters. ThereadJsonhelper correctly handles both string and Buffer chunks from the request stream.
100-111: Correct and defensive async iteration over request stream.The
readJsonhelper properly handles the async iterable protocol, buffers chunks, and safely parses empty payloads. The distinction betweentypeof chunk === 'string'and Buffer is correct for handling different Node versions.versioned_docs/version-3.x/service/server-adapter.md (1)
50-50: Custom adapter catalog entry is correctly placed and formatted.The addition to the catalog follows the established pattern and the link path is consistent with the file structure introduced in the PR.
versioned_docs/version-3.x/service/api-handler/rpc.md (1)
237-265: RPC handler customization section is clear and mirrors REST handler pattern well.The section effectively demonstrates query decoding customization and properly documents the Node Buffer dependency with a fallback suggestion for edge runtimes. The tip at the end provides good continuity with the comprehensive Custom API Handler guide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds comprehensive documentation for customizing API handlers and server adapters in ZenStack v3. The documentation covers extension patterns for the built-in REST and RPC handlers, as well as guidance for implementing custom handlers and server adapters from scratch.
Key Changes:
- Added dedicated custom handler guide with ApiHandler contract details and extension patterns
- Extended REST and RPC handler documentation with concrete override examples
- Added custom server adapter walkthrough with minimal Node HTTP implementation
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
versioned_docs/version-3.x/service/server-adapter.md |
Added navigation link to custom server adapter documentation |
versioned_docs/version-3.x/service/api-handler/rpc.md |
Added customization section with unmarshalQ override example and cross-reference |
versioned_docs/version-3.x/service/api-handler/rest.md |
Added customization section with buildFilter override example and cross-reference; removed blank line |
versioned_docs/version-3.x/service/api-handler/custom.md |
New comprehensive guide covering handler extension patterns and custom implementation |
versioned_docs/version-3.x/reference/server-adapters/custom.mdx |
New guide for building custom server adapters with Node HTTP example |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
versioned_docs/version-3.x/reference/server-adapters/custom.mdx
Outdated
Show resolved
Hide resolved
versioned_docs/version-3.x/reference/server-adapters/custom.mdx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (4)
versioned_docs/version-3.x/service/api-handler/custom.md (4)
12-16: Address grammar and punctuation issues flagged in prior review.Line 12 is a run-on sentence and uses "brand new" which should be "brand-new" (hyphenation for compound adjective). Lines 14–16 have inconsistent punctuation: the first two items end with semicolons, the last ends with a period. Apply one of the following fixes:
- Option 1: Remove all punctuation (preferred for short items):
- override parts of the REST or RPC pipeline (filtering, serialization, validation, error handling, and more); - wrap the default handlers with extra behavior (multi-tenancy, telemetry, custom logging); - implement a handler from scratch while still benefiting from ZenStack's schema and serialization helpers. + override parts of the REST or RPC pipeline (filtering, serialization, validation, error handling, and more) + wrap the default handlers with extra behavior (multi-tenancy, telemetry, custom logging) + implement a handler from scratch while still benefiting from ZenStack's schema and serialization helpers
- Option 2: Rewrite line 12 to break the run-on and fix hyphenation:
- ZenStack ships ready-to-use REST and RPC handlers, but you can tailor their behavior or author brand new handlers without leaving TypeScript. The server package exposes the handler contracts through `@zenstackhq/server/types` and utility helpers from `@zenstackhq/server/api`. All built-in handlers expose their methods as `protected` to allow for extension points. You can: + ZenStack ships ready-to-use REST and RPC handlers, but you can tailor their behavior or author brand-new handlers without leaving TypeScript. All built-in handlers expose their methods as `protected` to allow for extension points. You can:
39-48: Clarify generic type parameter for RestApiHandlerOptions.The import at line 40 shows
type RestApiHandlerOptionsbut the constructor parameter (line 46) is generic. Add a brief comment in the import block or just above the constructor to clarify thatRestApiHandlerOptionsmust be parameterized with the schema type:import { RestApiHandler, type RestApiHandlerOptions } from '@zenstackhq/server/api'; import { schema } from '~/zenstack/schema'; type Schema = typeof schema; class PublishedOnlyRestHandler extends RestApiHandler<Schema> { constructor(options: RestApiHandlerOptions<Schema>) { + // RestApiHandlerOptions is generic and must be parameterized with your schema type super(options); }
56-59: Add inline comment explaining the type guard logic.The defensive check at lines 57–59 ensures the filter is a plain object before spreading. Add a brief comment to clarify the intent:
const existing = base.filter && typeof base.filter === 'object' && !Array.isArray(base.filter) - ? { ...(base.filter as Record<string, unknown>) } + ? { ...(base.filter as Record<string, unknown>) } // ensure filter is a plain object before spreading : {};
114-120: Use consistent terminology for examples and simplify "Refer back" phrasing.Line 116 uses "for example" in parentheses, which is inconsistent with standardization on "e.g." elsewhere in the documentation. Additionally, line 119 uses "Refer back to" which may be wordy. Apply this fix:
- `processRequestPayload` for enforcing per-request invariants (for example, injecting tenant IDs); + `processRequestPayload` for enforcing per-request invariants (e.g., injecting tenant IDs);And for line 119–120:
- Refer back to the [RPC API Handler](./rpc) page for the canonical behavior and endpoint matrix. + For canonical behavior and endpoint matrix, see [RPC API Handler](./rpc).
🧹 Nitpick comments (1)
versioned_docs/version-3.x/service/api-handler/custom.md (1)
77-83: Simplify "Refer back" phrasing.Line 82 uses "Refer back to" which may be considered wordy. Consider a shorter alternative like "See" or "For details, see":
- Refer back to the [RESTful API Handler](./rest) page for the canonical behavior and extension points. + For canonical behavior and extension points, see [RESTful API Handler](./rest).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
versioned_docs/version-3.x/reference/server-adapters/custom.mdx(1 hunks)versioned_docs/version-3.x/service/api-handler/custom.md(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- versioned_docs/version-3.x/reference/server-adapters/custom.mdx
🧰 Additional context used
🪛 LanguageTool
versioned_docs/version-3.x/service/api-handler/custom.md
[grammar] ~12-~12: Use a hyphen to join words.
Context: ...an tailor their behavior or author brand new handlers without leaving TypeScript....
(QB_NEW_EN_HYPHEN)
[style] ~82-~82: ‘Refer back’ might be wordy. Consider a shorter alternative.
Context: ...Ids` to expose bespoke query features. Refer back to the RESTful API Handler pa...
(EN_WORDINESS_PREMIUM_REFER_BACK)
[style] ~119-~119: ‘Refer back’ might be wordy. Consider a shorter alternative.
Context: ...subset of models to a specific client. Refer back to the RPC API Handler page fo...
(EN_WORDINESS_PREMIUM_REFER_BACK)
🔇 Additional comments (3)
versioned_docs/version-3.x/service/api-handler/custom.md (3)
18-33: Core building blocks section is well‑structured.The imports and accompanying descriptions clearly explain the role of each utility. This section sets up the foundation well for the handler extension examples.
122-155: "Implementing a handler from scratch" section is clear and correct.The minimal
HealthcheckHandlerexample effectively demonstrates theApiHandlercontract, including theschemaproperty,loggetter, and asynchandleRequestmethod. The emphasis onregisterCustomSerializers()is appropriate and prevents a common integration pitfall.
157-173: Integration example is practical and well-linked.The Express middleware example clearly demonstrates how custom handlers integrate with server adapters via the shared
apiHandleroption. The cross-link to custom server adapter documentation supports the PR's goal of surfacing customization workflows from multiple entry points.
- add custom API handler guide with extension examples - update REST and RPC handler docs with customization guidance - add custom server adapter reference and link from catalog - refresh sidebar entries for the new content
8f047a7 to
a873b9a
Compare
Summary
ApiHandlercontract, REST/RPC subclass hooks, and integration patternsAdditional Context
Related Work
Summary by CodeRabbit