126 lines
3.7 KiB
Markdown
126 lines
3.7 KiB
Markdown
---
|
|
title: Blog API
|
|
tags: [api, blog, reference]
|
|
---
|
|
|
|
# Blog API
|
|
|
|
Endpoints live under `/api/blog/*`. The router is [`backend/src/routes/blogRoutes.ts`](../../backend/src/routes/blogRoutes.ts) and delegates to [`blogController`](../../backend/src/services/blog/blogController.ts).
|
|
|
|
Public endpoints (post listing and reads) are open. Mutating endpoints (create/update/delete) require **admin** role — enforced via `authenticateToken` + `authorizeRoles('admin')`.
|
|
|
|
Model: [[BlogPost]]. Image uploads use the [[File API]] (`POST /api/files/upload/blog-images`).
|
|
|
|
## Public reads
|
|
|
|
### GET /api/blog/posts
|
|
|
|
**Description:** Paginated list of published blog posts.
|
|
**Auth required:** No
|
|
**Query params:**
|
|
- `page` (default 1)
|
|
- `limit` (default 10)
|
|
- `category`
|
|
- `tag`
|
|
- `search` (matches title/excerpt/content)
|
|
- `sortBy` (default `publishedAt`)
|
|
- `sortOrder` (`asc` | `desc`, default `desc`)
|
|
**Response 200:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"posts": [BlogPost, ...],
|
|
"pagination": { "page": 1, "limit": 10, "total": 25, "totalPages": 3, "hasMore": true }
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /api/blog/posts/featured
|
|
|
|
**Description:** Posts with `isFeatured: true`. Used by the home page hero strip.
|
|
**Auth required:** No
|
|
**Response 200:** `{ success, data: { posts } }`
|
|
|
|
### GET /api/blog/posts/recent
|
|
|
|
**Description:** Most recent N published posts. Used by the footer / sidebar.
|
|
**Auth required:** No
|
|
**Query params:** `limit` (default 5)
|
|
|
|
### GET /api/blog/posts/search
|
|
|
|
**Description:** Full-text search across title/excerpt/content/tags.
|
|
**Auth required:** No
|
|
**Query params:** `q` (required), `page`, `limit`
|
|
**Errors:** `400` if `q` is missing or shorter than 2 characters.
|
|
|
|
### GET /api/blog/posts/:slug
|
|
|
|
**Description:** Get a single published post by URL slug.
|
|
**Auth required:** No
|
|
**Response 200:** `{ success, data: { post: BlogPost } }`
|
|
**Errors:** `404` not found or not published.
|
|
**Side effects:** Increments `viewsCount`.
|
|
|
|
## Admin (mutating)
|
|
|
|
All endpoints below require `Bearer JWT` with `role: "admin"`.
|
|
|
|
### GET /api/blog/admin/posts
|
|
|
|
**Description:** Admin list including drafts and unpublished posts.
|
|
**Auth required:** Bearer JWT (admin)
|
|
**Query params:** `page`, `limit`, `status` (`draft` | `published` | `archived`), `search`
|
|
**Response 200:** `{ success, data: { posts, pagination } }`
|
|
|
|
### GET /api/blog/admin/posts/:id
|
|
|
|
**Description:** Get a post by id (admin view, includes draft fields).
|
|
**Auth required:** Bearer JWT (admin)
|
|
|
|
### POST /api/blog/posts
|
|
|
|
**Description:** Create a post.
|
|
**Auth required:** Bearer JWT (admin)
|
|
**Request body:**
|
|
```ts
|
|
{
|
|
title: string;
|
|
slug?: string; // auto-generated from title when omitted
|
|
excerpt?: string;
|
|
content: string; // Markdown / rich text
|
|
coverImage?: string; // URL from [[File API]]
|
|
category?: string;
|
|
tags?: string[];
|
|
status?: "draft" | "published"; // default "draft"
|
|
isFeatured?: boolean;
|
|
publishedAt?: string; // ISO date, used when status === "published"
|
|
videoUrl?: string;
|
|
metadata?: Record<string, unknown>;
|
|
}
|
|
```
|
|
**Response 201:** `{ success, data: { post } }`
|
|
|
|
### PUT /api/blog/posts/:id
|
|
|
|
**Description:** Update a post. Partial; the body can contain any of the create fields.
|
|
**Auth required:** Bearer JWT (admin)
|
|
|
|
### DELETE /api/blog/posts/:id
|
|
|
|
**Description:** Hard-delete a post.
|
|
**Auth required:** Bearer JWT (admin)
|
|
**Response 200:** `{ success: true, message: "Post deleted" }`
|
|
|
|
## Comments
|
|
|
|
The codebase does not currently expose a comments API — comments are intentionally disabled. If/when added, they will appear under `/api/blog/posts/:id/comments`.
|
|
|
|
## Related
|
|
|
|
- [[BlogPost]]
|
|
- [[File API]] (for cover and inline image uploads)
|
|
- `backend/BLOG_API_ENDPOINTS.md` (legacy in-repo notes)
|
|
- `backend/BLOG_VIDEO_EXAMPLES.md`
|