117 lines
3.5 KiB
Markdown
117 lines
3.5 KiB
Markdown
# Client SDK Usage Guide
|
||
|
||
This project uses an auto-generated SDK powered by `@hey-api/openapi-ts` to interact with the PayloadCMS multi-tenant backend.
|
||
|
||
## SDK Structure
|
||
|
||
- **Core Methods**: `src/clientsdk/sdk.gen.ts` (Contains classes like `Posts`, `Categories`, `Pages`, `Media`)
|
||
- **Type Definitions**: `src/clientsdk/types.gen.ts` (Contains interfaces like `Post`, `Category`, `Media`)
|
||
- **Query Serializer**: `src/clientsdk/querySerializer.ts` (Handles nested object serialization for PayloadCMS queries)
|
||
- **Client Factory**: `src/clientsdk/client/index.ts` (Use `createClient` to initialize a client instance)
|
||
|
||
## 1. Initialization
|
||
|
||
You must initialize the client with the correct `baseUrl`, `querySerializer`, and tenant headers.
|
||
|
||
```typescript
|
||
import { createClient } from '../clientsdk/client';
|
||
import { customQuerySerializer } from '../clientsdk/querySerializer';
|
||
import { TENANT_SLUG, TENANT_API_KEY, API_URL } from '../config';
|
||
|
||
const client = createClient({
|
||
baseUrl: API_URL,
|
||
querySerializer: customQuerySerializer, // CRITICAL: Required for nested where queries
|
||
headers: {
|
||
'X-Tenant-Slug': TENANT_SLUG,
|
||
'X-API-Key': TENANT_API_KEY,
|
||
},
|
||
});
|
||
```
|
||
|
||
## 2. Common Operations
|
||
|
||
### Fetching a List (with Sorting & Limits)
|
||
```typescript
|
||
import { Posts } from '../clientsdk/sdk.gen';
|
||
|
||
const response = await Posts.listPosts({
|
||
client,
|
||
query: {
|
||
limit: 10,
|
||
sort: '-createdAt', // Prefix with '-' for descending
|
||
},
|
||
});
|
||
|
||
// Access the data
|
||
const posts = response.data?.docs || [];
|
||
```
|
||
|
||
### Fetching a Single Document by Slug (Filtering)
|
||
PayloadCMS uses a specific `where` query syntax. The `customQuerySerializer` handles the translation to `where[slug][equals]=my-slug`.
|
||
|
||
```typescript
|
||
const response = await Posts.listPosts({
|
||
client,
|
||
query: {
|
||
where: {
|
||
slug: {
|
||
equals: 'my-article-slug',
|
||
},
|
||
},
|
||
limit: 1,
|
||
},
|
||
});
|
||
|
||
const post = response.data?.docs?.[0];
|
||
```
|
||
|
||
### Filtering by Category Slug
|
||
```typescript
|
||
const response = await Posts.listPosts({
|
||
client,
|
||
query: {
|
||
where: {
|
||
'categories.slug': {
|
||
equals: 'news',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
```
|
||
|
||
## 3. Data Patterns
|
||
|
||
### Relationships
|
||
- **Categories**: In this project, categories are a **many-to-many** relationship. Always treat `post.categories` as an array.
|
||
- Correct: `post.categories?.[0]?.title`
|
||
- Incorrect: `post.category.title`
|
||
- **Media**: Images (like `heroImage`) are objects containing `url`, `alt`, and `sizes`.
|
||
- Example: `<img src={post.heroImage?.url} alt={post.heroImage?.alt} />`
|
||
|
||
### Rich Text (Lexical)
|
||
PayloadCMS provides Lexical rich text. We typically use `post.content_html` which is pre-rendered to HTML on the server.
|
||
- **React**: `<div dangerouslySetInnerHTML={{ __html: post.content_html }} />`
|
||
- **Vue**: `<div v-html="post.content_html" />`
|
||
- **Astro**: `<div set:html={post.content_html} />`
|
||
|
||
## 4. TypeScript Usage
|
||
|
||
Always use the generated types for better DX and safety.
|
||
|
||
```typescript
|
||
import type { Post, Category, Media } from '../clientsdk/types.gen';
|
||
|
||
function formatPost(post: Post) {
|
||
return {
|
||
title: post.title,
|
||
date: new Date(post.createdAt).toLocaleDateString()
|
||
};
|
||
}
|
||
```
|
||
|
||
## 5. Troubleshooting
|
||
|
||
- **CORS Issues**: Ensure `API_URL` in `config.ts` matches the backend port (default 3000).
|
||
- **Empty Results**: Check if the `X-Tenant-Slug` header matches the slug assigned to your content in the CMS admin panel.
|
||
- **Nested Query Error**: If you see "Deeply-nested arrays/objects aren’t supported", verify that you are passing the `customQuerySerializer` to the `createClient` options.
|