Guides
Transforming Operation Examples
Zudoku allows you to transform operation examples in both request and response sections of your API documentation. This feature is particularly useful when you need to:
- Modify example data before displaying it
- Add dynamic values to examples
- Format examples in a specific way
- Filter or transform example content based on certain conditions
Configuration
To use this feature, you need to configure the transformExamples
function in your zudoku.config.tsx
file. Here's how to do it:
import type { ZudokuConfig } from "zudoku"; const config: ZudokuConfig = { // ... other config options ... defaults: { apis: { transformExamples: (options) => { // Transform the content here return options.content; }, }, }, };tsx
The Transform Function
The transformExamples
function receives an options object with the following properties:
content
: An array of Content objects containing the example dataoperation
: The operation being displayedtype
: Either "request" or "response" indicating which type of example is being transformedauth
: The current authentication statecontext
: ZudokContext
The function should return an array of Content objects with the transformed examples.
Example Usage
Here's a practical example showing how to transform examples:
const config: ZudokuConfig = { defaults: { apis: { transformExamples: ({ content, type }) => { // Example: Add a timestamp to all examples const timestamp = new Date().toISOString(); return content.map((contentItem) => ({ ...contentItem, example: { ...contentItem.example, timestamp, // You can modify other example properties here }, })); }, }, }, };tsx
Use Cases
Adding Dynamic Values
transformExamples: ({ content, auth }) => { const apiKey = auth.accessToken; return content.map((contentItem) => ({ ...contentItem, example: { ...contentItem.example, headers: { ...contentItem.example.headers, Authorization: `Bearer ${apiKey}`, }, }, })); };tsx
Formatting Examples
transformExamples: ({ content }) => { return content.map((contentItem) => ({ ...contentItem, example: { ...contentItem.example, // Format dates in a specific way createdAt: new Date(contentItem.example.createdAt).toLocaleDateString(), // Format numbers with specific precision amount: Number(contentItem.example.amount).toFixed(2), }, })); };tsx
Conditional Transformation
transformExamples: ({ content, auth, type }) => { const isAuthenticated = auth.isAuthenticated; return content.map((contentItem) => ({ ...contentItem, example: isAuthenticated ? contentItem.example // Show full example for authenticated users : { ...contentItem.example, sensitiveData: undefined }, // Hide sensitive data for unauthenticated users })); };tsx
Using JWT Claims
transformExamples: async ({ content, auth, context }) => { const token = await context.authentication.getAccessToken(); // Decode the JWT (this is a simple example - in production you might want to use a proper JWT library) const [, payload] = token.split("."); const decodedPayload = JSON.parse(atob(payload)); return content.map((contentItem) => ({ ...contentItem, example: { ...contentItem.example, // Add user-specific data from the JWT userId: decodedPayload.sub, organizationId: decodedPayload.org_id, // You can add any other claims from the JWT role: decodedPayload.role, }, })); };tsx
Best Practices
- Always return an array of Content objects, even if you're not transforming the content
- Preserve the original content structure while making your modifications
- Handle errors gracefully to prevent breaking the documentation
- Consider performance implications when transforming large examples
- Use the provided options object to access relevant information for your transformations