Skip to content

Feature/blog cms public api#12

Open
vH192Hv wants to merge 7 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-public-api
Open

Feature/blog cms public api#12
vH192Hv wants to merge 7 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-public-api

Conversation

@vH192Hv

@vH192Hv vH192Hv commented Jul 11, 2026

Copy link
Copy Markdown

设计方案

新增公开 REST API

GET /api/blog/:slug

响应格式

成功 (200):

{
  "id": "uuid",
  "title": "Post Title",
  "slug": "post-slug",
  "content": "Markdown content...",
  "excerpt": "Short description",
  "coverImage": "https://...",
  "status": "PUBLISHED",
  "authorId": "uuid",
  "author": { "id": "uuid", "username": "admin" },
  "tags": [
    { "id": "uuid", "name": "Getting Started", "slug": "getting-started" }
  ],
  "publishedAt": "2026-01-01T00:00:00.000Z",
  "createdAt": "2025-12-01T00:00:00.000Z",
  "updatedAt": "2026-01-01T00:00:00.000Z"
}

未找到或未发布 (404):

{ "error": "Post not found" }

缺少参数 (400):

{ "error": "Slug parameter is required" }

安全设计

检查 行为
slug 参数缺失或非字符串 400 Bad Request
帖子不存在 404 Not Found
帖子状态 ≠ PUBLISHED 404 Not Found(不暴露草稿/归档)
认证 不需要 — 完全公开
Date 序列化 所有时间戳通过 .toISOString() 序列化

Wasp Spec 声明

// blog-cms.wasp.ts
import { api } from "@wasp.sh/spec";
api("GET", "/api/blog/:slug", getPublishedPostBySlugApi),

与现有查询的关系

此 API 端点补充了 Branch 2 中已实现的 Wasp Query:

  • getPostBySlug — Wasp Query(同功能,供 Wasp 前端调用)
  • getPublishedPostBySlugApi — REST API(供外部消费者如 Astro 博客调用)

两者返回相同数据结构,仅调用方式不同。

执行方案

  • operations.ts 添加 GetPublishedPostBySlugApi 类型导入
  • 实现 getPublishedPostBySlugApi handler(slug 校验 + 404 + Date 序列化)
  • blog-cms.wasp.ts 声明 API 路由
  • 修正 api() spec 签名格式适配 Wasp v0.24+

文件变更

文件 操作 行数
template/app/src/blog-cms/operations.ts 修改 +30
template/app/src/blog-cms/blog-cms.wasp.ts 修改 +3

🔽 依赖 PR2 (operations) — 合并顺序第 3(与 PR3 并行)

vH192Hv and others added 7 commits July 9, 2026 21:30
- Add Post model with title, slug, content, excerpt, coverImage, status, timestamps
- Add Tag model with name and slug
- Add PostTag join table for many-to-many relationship
- Add PostStatus enum (DRAFT, PUBLISHED, ARCHIVED)
- Add posts relation to User model

Co-Authored-By: Claude <noreply@anthropic.com>
- Add seedBlogPosts function with sample posts and tags
- Register seed in main.wasp.ts db.seeds array

Co-Authored-By: Claude <noreply@anthropic.com>
- Define getAllPosts, getPost, getPostBySlug, getPublishedPosts queries
- Define createPost, updatePost, deletePost actions
- Define getAllTags, createTag, deleteTag tag operations
- Register blogCmsSpec in main.wasp.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- Add isValidSlug, generateSlug with regex format + length checks
- Add ALLOWED_TRANSITIONS map and transition validation helpers
- File is browser+server safe (no wasp/server imports)

Co-Authored-By: Claude <noreply@anthropic.com>
…rmissions)

- Post queries: getAllPosts (admin, paginated, filters), getPost (admin, by ID),
  getPostBySlug (public, PUBLISHED only), getPublishedPosts (public, paginated)
- Post mutations: createPost (slug gen/validate, status validation),
  updatePost (status transitions, tag replacement, publishedAt mgmt),
  deletePost (by ID with existence check)
- Tag operations: getAllTags (with post count), createTag (name/slug uniqueness),
  deleteTag (cascade removes PostTag entries)
- Permission guard: requireAdmin on all mutating + admin-read operations
- Slug helpers imported from shared utils.ts
- Status transitions validated via isAllowedTransition from utils.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- GET /api/blog/:slug returns published post with author and tags
- Returns 400 for missing slug, 404 for non-published or missing posts
- Proper Date serialization (toISOString) for all timestamp fields
- No authentication required

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant