feat(studio): Global REST API Console with auto-discovery#892
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Add useApiDiscovery hook for automatic endpoint discovery from metadata - Add ApiConsolePage component with endpoint tree, search, request/response panels - Add api-console view to App.tsx routing - Add API Console entry to sidebar under System section - Update site-header breadcrumb for api-console view - Add tests for API discovery logic Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…aming Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 仔细评估是否已经完成了任务中要求的所有开发 |
Replace static query params cheatsheet with interactive form table: - Add/remove query parameter rows with key/value inputs - Toggle individual params enabled/disabled (checkbox) - Quick-add preset buttons for common OData params ($top, $skip, $sort, $select, $count, $filter) - URL preview shows full path with appended query string - Replay from history restores query params into form - Add test for query param URL building logic Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
经过仔细评估,发现 Query Params 表单化填写 功能缺失(issue 明确要求 "支持 Query Params/Table(OData/数据分页等)表单化填写"),已在 当前所有 Done Criteria 完成状态: ✅ Studio 顶级 API 控制台可自动发现所有 REST API,分组浏览,搜索测试
✅ 用户无需手写端点,任意 Object 增删自动刷新、端点自动出现
✅ 支持请求/响应查看、历史记录、基本参数/Body 表单化填写
✅ 后续任务
|
There was a problem hiding this comment.
Pull request overview
Adds a top-level “API Console” view to Studio that auto-discovers REST endpoints from platform metadata and provides a request/response UI for testing them.
Changes:
- Added
ApiConsolePage(endpoint tree + request editor + response viewer + in-memory history/replay). - Added
useApiDiscoveryhook to build endpoint groups from metadata (objects + metadata types) plus some static system/auth endpoints. - Wired the new view into Studio navigation (App view routing, sidebar entry, header breadcrumb) and marked the roadmap item complete; added discovery-focused tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/studio/src/hooks/use-api-discovery.ts | Discovers metadata types/objects and builds grouped endpoint definitions for the API Console |
| apps/studio/src/components/ApiConsolePage.tsx | Renders the global API Console UI and executes requests via fetch |
| apps/studio/test/api-discovery.test.ts | Adds tests for object discovery assumptions, endpoint generation/grouping, and query param URL building |
| apps/studio/src/App.tsx | Adds api-console to the view union and renders ApiConsolePage |
| apps/studio/src/components/app-sidebar.tsx | Adds an “API Console” entry under System and expands view type unions |
| apps/studio/src/components/site-header.tsx | Adds breadcrumb label for the api-console view |
| ROADMAP.md | Marks “Global REST API Console” as completed |
| const AUTH_ENDPOINTS: EndpointDef[] = [ | ||
| { method: 'POST', path: '/api/auth/sign-in/email', desc: 'Sign in (email)', group: 'Auth', bodyTemplate: { email: 'user@example.com', password: '' } }, | ||
| { method: 'POST', path: '/api/auth/sign-up/email', desc: 'Sign up (email)', group: 'Auth', bodyTemplate: { email: '', password: '', name: '' } }, | ||
| { method: 'POST', path: '/api/auth/sign-out', desc: 'Sign out', group: 'Auth' }, | ||
| { method: 'GET', path: '/api/auth/session', desc: 'Get session', group: 'Auth' }, |
There was a problem hiding this comment.
Auth endpoints here are hardcoded under /api/auth/... and include /session, but the platform AuthPlugin defaults to /api/v1/auth and better-auth’s session endpoint is get-session. As-is, these entries will point to non-existent routes in the default ObjectStack server setup; please align paths with the configured auth basePath (default /api/v1/auth) and the actual better-auth endpoint names.
| // 2. Fetch object names from metadata | ||
| let objectNames: string[] = []; | ||
| try { | ||
| const objectType = metaTypes.includes('objects') ? 'objects' : metaTypes.includes('object') ? 'object' : null; | ||
| if (objectType) { | ||
| const objectResult = await client.meta.getItems(objectType); |
There was a problem hiding this comment.
Object discovery currently depends on client.meta.getTypes() succeeding; if it fails (or returns an unexpected shape), metaTypes stays empty and objectType becomes null, so no objects are fetched and no CRUD endpoints are generated. Consider falling back to probing getItems('object')/getItems('objects') directly (or defaulting to 'object') when types discovery is unavailable, so the console still discovers data endpoints in minimal/legacy environments.
| const baseUrl = (client as any)?.baseUrl ?? ''; | ||
| const fullUrl = `${baseUrl}${effectiveUrl}`; | ||
|
|
||
| setLoading(true); | ||
| const start = performance.now(); | ||
|
|
||
| try { | ||
| const fetchOptions: RequestInit = { | ||
| method: effectiveMethod, | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| }; |
There was a problem hiding this comment.
sendRequest uses fetch() directly, which bypasses ObjectStackClient’s request wrapper (e.g., token → Authorization header) and doesn’t set credentials. This can break the PR’s goal of “inheriting platform authentication” for protected APIs, especially in server mode when baseUrl is absolute. Consider reusing the client’s fetch implementation (or at least forwarding Authorization when configured and setting credentials: 'include' for cookie-based sessions).
| const contentType = res.headers.get('content-type') ?? ''; | ||
| if (contentType.includes('json')) { | ||
| const json = await res.json(); | ||
| bodyText = JSON.stringify(json, null, 2); | ||
| } else { | ||
| bodyText = await res.text(); | ||
| } |
There was a problem hiding this comment.
If the server responds with Content-Type: application/json but returns a non-JSON body (or an empty body), await res.json() will throw and the catch block reports it as a “Network Error” with status 0, losing the real HTTP status/body. Consider guarding JSON parsing (try JSON parse, fallback to res.text()), so responses are still visible even when the payload is malformed.
Studio's
ObjectApiConsoleonly tests CRUD for a single object with hardcoded endpoints. This adds a top-level API Console that auto-discovers all registered REST APIs from platform metadata.New files
src/hooks/use-api-discovery.ts— Hook that queriesclient.meta.getTypes()andclient.meta.getItems()to dynamically build the full endpoint tree (CRUD per object + system/auth/metadata endpoints), grouped and sorted by categorysrc/components/ApiConsolePage.tsx— Three-panel console: collapsible endpoint tree with search/filter, request editor (method selector, URL bar, JSON body), form-based query parameter editor, response viewer with status/timing/copy/history/replaytest/api-discovery.test.ts— 5 tests covering object discovery, endpoint generation, grouping logic, idempotent re-discovery, and query param URL buildingModified files
App.tsx— Added'api-console'toViewTypeunion and view routingapp-sidebar.tsx— "API Console" entry under System sectionsite-header.tsx— Breadcrumb support forapi-consoleviewROADMAP.md— Marked Global REST API Console as completeKey design decisions
refresh()— no polling, no stale cachefetch+(client as any).baseUrlpattern from existingObjectApiConsole$top,$skip,$sort,$select,$count,$filter), and live URL preview showing the full path with appended query stringOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.