bknd-api-discovery

📁 cameronapak/bknd-skills 📅 Jan 21, 2026
8
总安装量
6
周安装量
#35082
全站排名
安装命令
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-api-discovery

Agent 安装分布

gemini-cli 4
codex 4
cursor 3
antigravity 3
junie 3
windsurf 3

Skill 文档

API Discovery

Explore and understand Bknd’s auto-generated REST API endpoints.

Prerequisites

  • Running Bknd instance (local or deployed)
  • Access to admin panel (optional but helpful)
  • Basic understanding of REST APIs

When to Use UI Mode

  • Browsing available entities and their fields
  • Viewing schema structure visually
  • Quick endpoint exploration via browser

UI steps: Admin Panel > Data > Entities

When to Use Code Mode

  • Listing all registered routes programmatically
  • Understanding endpoint patterns for integration
  • Debugging route registration issues
  • Building API documentation

Understanding Bknd’s API Structure

Bknd auto-generates REST endpoints for all configured modules:

┌─────────────────────────────────────────────────────────────┐
│                    Bknd API Structure                       │
├─────────────────────────────────────────────────────────────┤
│  /api/data      → CRUD for all entities                     │
│  /api/auth      → Authentication (login, register, logout)  │
│  /api/media     → File uploads and serving                  │
│  /api/system    → System operations                         │
│  /flow          → Flow management and triggers              │
│  /admin         → Admin UI (if enabled)                     │
└─────────────────────────────────────────────────────────────┘

Code Approach

Step 1: List All Routes (CLI)

Use the debug command to list all registered routes:

bknd debug routes

Output:

GET     /admin/*
GET     /api/auth/me
POST    /api/auth/password/login
POST    /api/auth/logout
POST    /api/auth/register
GET     /api/data/:entity
POST    /api/data/:entity
GET     /api/data/:entity/:id
PATCH   /api/data/:entity/:id
DELETE  /api/data/:entity/:id
POST    /api/media/upload
GET     /api/media/:path
...

Step 2: Data API Endpoints

All entities get CRUD endpoints automatically:

Method Path Description SDK Method
GET /api/data/:entity List records api.data.readMany(entity)
POST /api/data/:entity/query List (complex query) api.data.readMany(entity, query)
GET /api/data/:entity/:id Get single record api.data.readOne(entity, id)
GET /api/data/:entity/:id/:ref Get related records api.data.readManyByReference(...)
POST /api/data/:entity Create record(s) api.data.createOne/Many(entity, data)
PATCH /api/data/:entity/:id Update single api.data.updateOne(entity, id, data)
PATCH /api/data/:entity Update many api.data.updateMany(entity, where, data)
DELETE /api/data/:entity/:id Delete single api.data.deleteOne(entity, id)
DELETE /api/data/:entity Delete many api.data.deleteMany(entity, where)
POST /api/data/:entity/fn/count Count records api.data.count(entity, where)
POST /api/data/:entity/fn/exists Check existence api.data.exists(entity, where)

Example: Explore posts entity

# List all posts
curl http://localhost:7654/api/data/posts

# Get post by ID
curl http://localhost:7654/api/data/posts/1

# Get with query params
curl "http://localhost:7654/api/data/posts?limit=10&sort[created_at]=desc"

# Get with relations
curl "http://localhost:7654/api/data/posts?with[]=author&with[]=comments"

# Complex query via POST
curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{"where": {"status": "published"}, "limit": 10}'

Step 3: Auth API Endpoints

Method Path Description
GET /api/auth/me Current user info
POST /api/auth/:strategy/login Login (e.g., /api/auth/password/login)
POST /api/auth/register Register new user
POST /api/auth/logout Logout
GET /api/auth/:strategy/redirect OAuth redirect
GET /api/auth/:strategy/callback OAuth callback

Example:

# Check current user
curl http://localhost:7654/api/auth/me \
  -H "Authorization: Bearer $TOKEN"

# Login
curl -X POST http://localhost:7654/api/auth/password/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@test.com", "password": "pass123"}'

# Register
curl -X POST http://localhost:7654/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "new@test.com", "password": "pass123"}'

Step 4: Media API Endpoints

Method Path Description
POST /api/media/upload Upload file
GET /api/media/:path Serve/download file

Example:

# Upload file
curl -X POST http://localhost:7654/api/media/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@image.png"

# Serve file
curl http://localhost:7654/api/media/uploads/image.png

Step 5: Flow Endpoints

Method Path Description
GET /flow List all flows
GET /flow/:name Get flow details
GET /flow/:name/run Manually run flow
* Custom trigger path HTTP trigger endpoints

Example:

# List flows
curl http://localhost:7654/flow

# Run flow manually
curl http://localhost:7654/flow/my-flow/run

Step 6: Programmatic Route Discovery

Access route information from your code:

import { App } from "bknd";

const app = new App({ /* config */ });
await app.build();

// Get Hono server instance
const server = app.server;

// Routes are registered on the Hono instance
// Use bknd debug routes for listing

Step 7: Discover Entity Schema

Query the system to understand available entities:

import { Api } from "bknd";

const api = new Api({ host: "http://localhost:7654" });

// List available entities by checking which respond
const entities = ["posts", "users", "comments", "categories"];

for (const entity of entities) {
  const { ok } = await api.data.readMany(entity, { limit: 1 });
  if (ok) {
    console.log(`Entity exists: ${entity}`);
  }
}

Step 8: Response Format Discovery

All endpoints return consistent response format:

Success (list):

{
  "data": [
    { "id": 1, "title": "Post 1" },
    { "id": 2, "title": "Post 2" }
  ],
  "meta": {
    "total": 50,
    "limit": 20,
    "offset": 0
  }
}

Success (single):

{
  "data": { "id": 1, "title": "Post 1" }
}

Error:

{
  "error": {
    "message": "Record not found",
    "code": "NOT_FOUND"
  }
}

UI Approach: Admin Panel

Step 1: Access Admin Panel

Navigate to: http://localhost:7654/admin

Step 2: Browse Entities

  1. Click Data in sidebar
  2. View list of all entities
  3. Click entity to see:
    • All fields with types
    • Relationships
    • Sample data

Step 3: View Entity Structure

Admin panel shows:

  • Field names and types
  • Required vs optional fields
  • Default values
  • Relation configurations

Step 4: Test Queries

Admin panel provides:

  • Data browser for each entity
  • Filter/sort interface
  • Create/edit forms
  • Relationship navigation

Query Parameter Reference

Data Endpoints

Parameter Example Description
limit ?limit=10 Max records to return
offset ?offset=20 Skip N records
sort[field] ?sort[created_at]=desc Sort by field
where[field] ?where[status]=published Filter by field
with[] ?with[]=author Include relation
join[] ?join[]=author Join relation (same result)
select[] ?select[]=id&select[]=title Select specific fields

Complex Queries (POST)

curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{
    "where": {
      "status": "published",
      "views": { "$gt": 100 }
    },
    "sort": { "created_at": "desc" },
    "limit": 10,
    "offset": 0,
    "with": ["author", "category"]
  }'

SDK Method to Endpoint Mapping

import { Api } from "bknd";
const api = new Api({ host: "http://localhost:7654" });

// Method                        → Endpoint
api.data.readMany("posts")       // GET  /api/data/posts
api.data.readOne("posts", 1)     // GET  /api/data/posts/1
api.data.createOne("posts", {})  // POST /api/data/posts
api.data.updateOne("posts", 1, {})// PATCH /api/data/posts/1
api.data.deleteOne("posts", 1)   // DELETE /api/data/posts/1

api.auth.login("password", {})   // POST /api/auth/password/login
api.auth.register({})            // POST /api/auth/register
api.auth.logout()                // POST /api/auth/logout
api.auth.me()                    // GET  /api/auth/me

api.media.upload(file)           // POST /api/media/upload

Testing Endpoints

Quick Health Check

# Check if API is running
curl http://localhost:7654/api/auth/me
# Returns user info or 401

Explore Available Data

# Try common entity names
for entity in posts users comments products orders; do
  echo "Testing $entity..."
  curl -s -o /dev/null -w "%{http_code}" http://localhost:7654/api/data/$entity
  echo ""
done

Debug Script

async function discoverApi(host: string) {
  const api = new Api({ host });

  console.log("API Discovery Report");
  console.log("===================");

  // Test auth
  const { ok: authOk } = await api.auth.me();
  console.log(`Auth endpoint: ${authOk ? "working" : "requires auth"}`);

  // Test common entities
  const testEntities = ["posts", "users", "comments", "products"];
  for (const entity of testEntities) {
    const { ok, meta } = await api.data.readMany(entity, { limit: 1 });
    if (ok) {
      console.log(`Entity "${entity}": ${meta?.total ?? "?"} records`);
    }
  }
}

discoverApi("http://localhost:7654");

Common Pitfalls

Wrong Base Path

Problem: 404 errors on API calls

Fix: Use correct base paths:

# WRONG
curl http://localhost:7654/data/posts
curl http://localhost:7654/posts

# CORRECT
curl http://localhost:7654/api/data/posts

Auth Strategy in Path

Problem: Login fails

Fix: Include strategy name:

# WRONG
curl -X POST http://localhost:7654/api/auth/login

# CORRECT (password strategy)
curl -X POST http://localhost:7654/api/auth/password/login

Query vs GET Params

Problem: Complex queries don’t work via GET

Fix: Use POST for complex queries:

# Limited filtering via GET
curl "http://localhost:7654/api/data/posts?where[status]=published"

# Complex filtering via POST
curl -X POST http://localhost:7654/api/data/posts/query \
  -H "Content-Type: application/json" \
  -d '{"where": {"$or": [{"status": "published"}, {"featured": true}]}}'

Entity Name Mismatch

Problem: 404 on entity endpoints

Fix: Use exact entity names (case-sensitive, usually lowercase):

# WRONG
curl http://localhost:7654/api/data/Posts
curl http://localhost:7654/api/data/post

# CORRECT
curl http://localhost:7654/api/data/posts

Missing Content-Type

Problem: POST/PATCH returns 400

Fix: Include Content-Type header:

# WRONG
curl -X POST http://localhost:7654/api/data/posts \
  -d '{"title": "Test"}'

# CORRECT
curl -X POST http://localhost:7654/api/data/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "Test"}'

Endpoint Quick Reference

Module Base Path Key Operations
Data /api/data CRUD for all entities
Auth /api/auth Login, register, logout, me
Media /api/media Upload, serve files
Flows /flow List, view, run flows
Admin /admin Admin UI

DOs and DON’Ts

DO:

  • Use bknd debug routes to list all endpoints
  • Check admin panel for visual schema exploration
  • Use POST /query endpoint for complex filters
  • Include Content-Type header on POST/PATCH
  • Test endpoints with curl before implementing

DON’T:

  • Forget /api/ prefix on API paths
  • Mix up entity names (case matters)
  • Use GET for complex queries with nested operators
  • Assume entity names – verify they exist first
  • Forget auth strategy in login path (/api/auth/password/login)

Related Skills

  • bknd-client-setup – Set up SDK in frontend
  • bknd-crud-read – Query data with filtering
  • bknd-custom-endpoint – Create custom API endpoints
  • bknd-login-flow – Implement authentication
  • bknd-local-setup – Set up local development