Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Whether you're scaffolding a greenfield service from an OpenAPI contract, evolvi

## Features

- **Code generation from OpenAPI 3.0** — reads any valid OpenAPI 3.0 spec (JSON or YAML) and emits a complete, compilable MoonBit project with typed route registrations, request decoders, and handler stubs
- **Code generation from OpenAPI 3.0** — reads any valid OpenAPI 3.0 spec (JSON or YAML) and emits a complete, compilable MoonBit project with typed route registrations, request decoders, handler stubs, and a typed HTTP client
- **Regeneration-safe** — user-owned handler files are never overwritten on subsequent `generate` runs; only files carrying the `// Code generated by mapi. DO NOT EDIT.` header are updated
- **Spec drift detection** — `mapi diff` compares your current spec against the saved `.mapi/state.json` and surfaces added, removed, and unchanged routes before you regenerate
- **Host-adapter architecture** — the runtime core (`lib/`) is completely decoupled from I/O; any execution environment (Bun, Node, Deno, native Wasm) can be plugged in by implementing a thin host adapter
Expand All @@ -55,7 +55,7 @@ Or add to your `moon.mod.json` directly:
```json
{
"deps": {
"cogna-dev/mapi": "0.1.0"
"cogna-dev/mapi": "0.1.1"
}
}
```
Expand All @@ -79,8 +79,11 @@ my-api/
├── moon.mod.json
├── src/
│ ├── generated/ # DO NOT EDIT — regenerated by mapi
│ │ ├── routes.mbt # Route registrations, request decoders
│ │ ├── models.mbt # Request / response types
│ │ ├── schemas.mbt # OpenAPI schema models
│ │ ├── operations.mbt # Typed operation inputs / outputs
│ │ ├── contract.mbt # Handler contract for server implementation
│ │ ├── router.mbt # Route registrations and server glue
│ │ ├── client.mbt # Typed HTTP client generated from spec
│ │ └── moon.pkg
│ └── handlers/ # Your code — never overwritten
│ ├── get_users.mbt
Expand Down Expand Up @@ -212,6 +215,20 @@ assert_eq!(not_found.status, 404)

---

## Generated Typed HTTP Client

Each generated project now includes `src/generated/client.mbt`, which gives you a static-typed API client derived directly from the same OpenAPI contract used for server scaffolding.

- One typed client method per operation (`ApiClient::list_pets`, etc.)
- Strongly typed request input (`ListPetsInput`) and response output (`ListPetsResponse`)
- Path/query/body request shaping generated from OpenAPI parameters and requestBody
- JSON response decoding into generated MoonBit types
- Deterministic status-code handling (preferred success status from OpenAPI, or fallback to any `2xx`)

`ApiClient` is transport-agnostic: provide an `ApiTransport` with a `send` function that receives a `RequestEnvelope` and returns a `ResponseEnvelope`. This keeps the generated client reusable across Bun, Node, Deno, native hosts, and in-memory tests.

---

## Architecture

```
Expand All @@ -224,8 +241,8 @@ assert_eq!(not_found.status, 404)
▼
┌─────────────────────────────────────────────────────┐
│ Generated layer (src/generated/) │
│ routes.mbt · models.mbt │
│ Typed route registrations + request decoders │
│ schemas · operations · contract · router · client │
│ Typed server glue + typed HTTP client │
└──────────────────────┬──────────────────────────────┘
│ calls
▼
Expand Down
Loading
Loading