重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
jsonapi by prowler-cloud/prowler
npx skills add https://github.com/prowler-cloud/prowler --skill jsonapi本技能侧重于规范合规性。对于实现模式(ViewSets、Serializers、Filters),请将 django-drf 技能与此技能结合使用。
| 技能 | 侧重点 |
|---|---|
jsonapi | 规范要求的内容(MUST/MUST NOT 规则) |
django-drf | 如何在 DRF 中实现它(代码模式) |
创建/修改端点时,请同时调用这两个技能。
在创建或修改端点之前,务必根据最新规范进行验证:
如果 Context7 MCP 可用,直接查询 JSON:API 规范:
mcp_context7_resolve-library-id(query="jsonapi specification")
mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]")
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
如果 Context7 不可用,从官方规范获取:
WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]")
这确保了即使在规范更新后,也能符合最新的 JSON:API 版本。
data 和 errorsdata、errors、metatype 和 id(字符串)id(由服务器生成)Content-Type: application/vnd.api+jsonAccept: application/vnd.api+jsonext/profile,否则切勿向媒体类型添加参数id 必须使用字符串(即使是 UUID)type 必须使用小写短横线命名法id 或 type 放在 attributes 内部attributes 中包含外键 - 使用 relationshipslinks、data 或 meta{"type": "...", "id": "..."}{"errors": [...]}status 作为字符串包含(例如 "400",而不是 400)source.pointer| 操作 | 成功 | 异步 | 冲突 | 未找到 | 禁止 | 错误请求 |
|---|---|---|---|---|---|---|
| GET | 200 | - | - | 404 | 403 | 400 |
| POST | 201 | 202 | 409 | 404 | 403 | 400 |
| PATCH | 200 | 202 | 409 | 404 | 403 | 400 |
| DELETE | 200/204 | 202 | - | 404 | 403 | - |
| 状态码 | 使用场景 |
|---|---|
200 OK | 成功的 GET、带有响应体的 PATCH、带有响应的 DELETE |
201 Created | POST 创建资源(必须包含 Location 头) |
202 Accepted | 异步操作已启动(返回任务引用) |
204 No Content | 成功的 DELETE、没有响应体的 PATCH |
400 Bad Request | 无效的查询参数、格式错误的请求、未知字段 |
403 Forbidden | 认证通过但无权限,客户端生成的 ID 被拒绝 |
404 Not Found | 资源不存在 或 RLS 隐藏了它(切勿透露是哪种情况) |
409 Conflict | 重复的 ID、类型不匹配、关联关系冲突 |
415 Unsupported | 错误的 Content-Type 头 |
{
"data": {
"type": "providers",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"alias": "Production",
"connected": true
},
"relationships": {
"tenant": {
"data": {"type": "tenants", "id": "..."}
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
}
{
"data": [
{"type": "providers", "id": "...", "attributes": {...}},
{"type": "providers", "id": "...", "attributes": {...}}
],
"links": {
"self": "/api/v1/providers?page[number]=1",
"first": "/api/v1/providers?page[number]=1",
"last": "/api/v1/providers?page[number]=5",
"prev": null,
"next": "/api/v1/providers?page[number]=2"
},
"meta": {
"pagination": {"count": 100, "pages": 5}
}
}
{
"errors": [
{
"status": "400",
"code": "invalid",
"title": "Invalid attribute",
"detail": "UID must be 12 digits for AWS accounts",
"source": {"pointer": "/data/attributes/uid"}
}
]
}
| 类别 | 格式 | 示例 |
|---|---|---|
page | page[number], page[size] | ?page[number]=2&page[size]=25 |
filter | filter[field], filter[field__op] | ?filter[status]=FAIL |
sort | 逗号分隔,- 表示降序 | ?sort=-inserted_at,name |
fields | fields[type] | ?fields[providers]=id,alias |
include | 逗号分隔的路径 | ?include=provider,scan.task |
400include 路径,必须返回 400sort 字段,必须返回 400fields[type] 时,不得包含额外字段| 违规行为 | 错误示例 | 正确示例 |
|---|---|---|
| ID 为整数 | "id": 123 | "id": "123" |
| 类型使用驼峰命名法 | "type": "providerGroup" | "type": "provider-groups" |
| 外键放在属性中 | "tenant_id": "..." | "relationships": {"tenant": {...}} |
| 错误不是数组 | {"error": "..."} | {"errors": [{"detail": "..."}]} |
| 状态码为数字 | "status": 400 | "status": "400" |
| 同时包含数据和错误 | {"data": ..., "errors": ...} | 只能包含其中之一 |
| 缺少指针 | {"detail": "Invalid"} | {"detail": "...", "source": {"pointer": "..."}} |
PATCH /api/v1/providers/123/relationships/tenant
Content-Type: application/vnd.api+json
{"data": {"type": "tenants", "id": "456"}}
清空关联:{"data": null}
| 操作 | 方法 | 请求体 |
|---|---|---|
| 替换所有 | PATCH | {"data": [{...}, {...}]} |
| 添加成员 | POST | {"data": [{...}]} |
| 移除成员 | DELETE | {"data": [{...}]} |
include)当使用 ?include=provider 时:
{
"data": {
"type": "scans",
"id": "...",
"relationships": {
"provider": {
"data": {"type": "providers", "id": "prov-123"}
}
}
},
"included": [
{
"type": "providers",
"id": "prov-123",
"attributes": {"alias": "Production"}
}
]
}
django-drf 技能获取 DRF 特定模式prowler-test-api 技能获取测试模式每周安装量
55
代码仓库
GitHub 星标数
13.4K
首次出现
2026年1月23日
安全审计
安装于
codex53
opencode51
github-copilot50
gemini-cli49
cursor49
claude-code48
This skill focuses on spec compliance. For implementation patterns (ViewSets, Serializers, Filters), use django-drf skill together with this one.
| Skill | Focus |
|---|---|
jsonapi | What the spec requires (MUST/MUST NOT rules) |
django-drf | How to implement it in DRF (code patterns) |
When creating/modifying endpoints, invoke BOTH skills.
ALWAYS validate against the latest spec before creating or modifying endpoints:
If Context7 MCP is available, query the JSON:API spec directly:
mcp_context7_resolve-library-id(query="jsonapi specification")
mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]")
If Context7 is not available, fetch from the official spec:
WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]")
This ensures compliance with the latest JSON:API version, even after spec updates.
data and errors in the same responsedata, errors, metatype and id (string) in resource objectsid when creating resources (server generates it)Content-Type: application/vnd.api+jsonAccept: application/vnd.api+jsonext/profileid (even if UUID)typeid or type inside attributesattributes - use relationshipslinks, data, or meta{"type": "...", "id": "..."}{"errors": [...]}status as string (e.g., "400", not 400)source.pointer for field-specific errors| Operation | Success | Async | Conflict | Not Found | Forbidden | Bad Request |
|---|---|---|---|---|---|---|
| GET | 200 | - | - | 404 | 403 | 400 |
| POST | 201 | 202 |
| Code | Use When |
|---|---|
200 OK | Successful GET, PATCH with response body, DELETE with response |
201 Created | POST created resource (MUST include Location header) |
202 Accepted | Async operation started (return task reference) |
204 No Content | Successful DELETE, PATCH with no response body |
400 Bad Request | Invalid query params, malformed request, unknown fields |
{
"data": {
"type": "providers",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"alias": "Production",
"connected": true
},
"relationships": {
"tenant": {
"data": {"type": "tenants", "id": "..."}
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
}
{
"data": [
{"type": "providers", "id": "...", "attributes": {...}},
{"type": "providers", "id": "...", "attributes": {...}}
],
"links": {
"self": "/api/v1/providers?page[number]=1",
"first": "/api/v1/providers?page[number]=1",
"last": "/api/v1/providers?page[number]=5",
"prev": null,
"next": "/api/v1/providers?page[number]=2"
},
"meta": {
"pagination": {"count": 100, "pages": 5}
}
}
{
"errors": [
{
"status": "400",
"code": "invalid",
"title": "Invalid attribute",
"detail": "UID must be 12 digits for AWS accounts",
"source": {"pointer": "/data/attributes/uid"}
}
]
}
| Family | Format | Example |
|---|---|---|
page | page[number], page[size] | ?page[number]=2&page[size]=25 |
filter | filter[field], filter[field__op] | ?filter[status]=FAIL |
400 for unsupported query parameters400 for unsupported include paths400 for unsupported sort fieldsfields[type] is specified| Violation | Wrong | Correct |
|---|---|---|
| ID as integer | "id": 123 | "id": "123" |
| Type as camelCase | "type": "providerGroup" | "type": "provider-groups" |
| FK in attributes | "tenant_id": "..." | "relationships": {"tenant": {...}} |
| Errors not array |
PATCH /api/v1/providers/123/relationships/tenant
Content-Type: application/vnd.api+json
{"data": {"type": "tenants", "id": "456"}}
To clear: {"data": null}
| Operation | Method | Body |
|---|---|---|
| Replace all | PATCH | {"data": [{...}, {...}]} |
| Add members | POST | {"data": [{...}]} |
| Remove members | DELETE | {"data": [{...}]} |
include)When using ?include=provider:
{
"data": {
"type": "scans",
"id": "...",
"relationships": {
"provider": {
"data": {"type": "providers", "id": "prov-123"}
}
}
},
"included": [
{
"type": "providers",
"id": "prov-123",
"attributes": {"alias": "Production"}
}
]
}
django-drf skill for DRF-specific patternsprowler-test-api skill for test patternsWeekly Installs
55
Repository
GitHub Stars
13.4K
First Seen
Jan 23, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex53
opencode51
github-copilot50
gemini-cli49
cursor49
claude-code48
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
172,600 周安装
游戏化循环技能:动机心理学与参与度架构设计,实现道德游戏化与用户参与
183 周安装
设计概要撰写指南 - 专业模板与最佳实践 | 提升团队设计效率
193 周安装
React Spring Physics:基于物理的React动画库教程,实现自然UI动画与手势交互
183 周安装
Docker/Kubernetes容器调试指南:解决启动失败、性能瓶颈与网络问题
181 周安装
Three.js与WebGL开发专家 | 3D网页图形、React Three Fiber(R3F)与GLSL着色器开发
180 周安装
Readwise Reader 读者画像构建技能 - 基于阅读历史分析,实现个性化内容推荐与体验优化
186 周安装
409 |
404 |
403 |
400 |
| PATCH | 200 | 202 | 409 | 404 | 403 | 400 |
| DELETE | 200/204 | 202 | - | 404 | 403 | - |
403 Forbidden| Authentication ok but no permission, client-generated ID rejected |
404 Not Found | Resource doesn't exist OR RLS hides it (never reveal which) |
409 Conflict | Duplicate ID, type mismatch, relationship conflict |
415 Unsupported | Wrong Content-Type header |
sort | Comma-separated, - for desc | ?sort=-inserted_at,name |
fields | fields[type] | ?fields[providers]=id,alias |
include | Comma-separated paths | ?include=provider,scan.task |
{"error": "..."}{"errors": [{"detail": "..."}]} |
| Status as number | "status": 400 | "status": "400" |
| Data + errors | {"data": ..., "errors": ...} | Only one or the other |
| Missing pointer | {"detail": "Invalid"} | {"detail": "...", "source": {"pointer": "..."}} |