123 lines
2.8 KiB
Markdown
123 lines
2.8 KiB
Markdown
# Use Case 1: Quickstart — Build Your First OpenAPI-First Service
|
||
|
||
This guide walks you from an empty directory to a running, contract-driven service in a few minutes, then talks to it with the generated client.
|
||
|
||
---
|
||
|
||
## 🛠️ 1. Prerequisites
|
||
|
||
- Python 3.10+
|
||
- `openapi-first` installed (see [Overview](../01_overview.md#installation))
|
||
- `pip install "fastapi[standard]"` (or `uvicorn`) to run the app
|
||
|
||
---
|
||
|
||
## 📄 2. Write the OpenAPI document
|
||
|
||
OpenAPI comes first. Create `openapi.yaml`:
|
||
|
||
```yaml
|
||
openapi: 3.0.3
|
||
info:
|
||
title: Greeting Service
|
||
version: 1.0.0
|
||
servers:
|
||
- url: http://localhost:8000
|
||
paths:
|
||
/greet/{name}:
|
||
get:
|
||
operationId: get_greeting
|
||
parameters:
|
||
- name: name
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: A greeting
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
greeting:
|
||
type: string
|
||
```
|
||
|
||
Key points: every operation needs `operationId`, and every route must exist *only* here.
|
||
|
||
---
|
||
|
||
## 🧑💻 3. Write the handlers
|
||
|
||
Create `routes.py` — plain functions, no decorators, named exactly like the `operationId`s:
|
||
|
||
```python
|
||
# routes.py
|
||
def get_greeting(name: str) -> dict:
|
||
"""Return a greeting for the given name."""
|
||
return {"greeting": f"Hello, {name}!"}
|
||
```
|
||
|
||
If a handler is missing at startup, the app **refuses to boot** (`MissingOperationHandler`) — the fail-fast guarantee catches contract drift immediately.
|
||
|
||
---
|
||
|
||
## 🚀 4. Bootstrap the app
|
||
|
||
Create `main.py`:
|
||
|
||
```python
|
||
# main.py
|
||
from openapi_first.app import OpenAPIFirstApp
|
||
import routes
|
||
|
||
app = OpenAPIFirstApp(
|
||
openapi_path="openapi.yaml",
|
||
routes_module=routes,
|
||
title="Greeting Service",
|
||
)
|
||
```
|
||
|
||
Run it:
|
||
|
||
```bash
|
||
uvicorn main:app --reload
|
||
```
|
||
|
||
Visit `http://localhost:8000/docs` (Swagger UI) and `http://localhost:8000/openapi.json` — both are generated from *your* spec.
|
||
|
||
---
|
||
|
||
## 📡 5. Call it with the client
|
||
|
||
The same spec builds a strict client:
|
||
|
||
```python
|
||
# client.py
|
||
from openapi_first.loader import load_openapi
|
||
from openapi_first.client import OpenAPIClient
|
||
|
||
spec = load_openapi("openapi.yaml")
|
||
client = OpenAPIClient(spec)
|
||
|
||
response = client.get_greeting(path_params={"name": "Ada"})
|
||
print(response.status_code) # 200
|
||
print(response.json()) # {"greeting": "Hello, Ada!"}
|
||
```
|
||
|
||
---
|
||
|
||
## 💡 6. Next Steps
|
||
|
||
- Copy a fuller example: [02 – Templates](02_templates.md)
|
||
- Generate models/routes from a bigger spec: [04 – Codegen](04_codegen.md)
|
||
- Drive everything from a client: [03 – Client](03_client.md)
|
||
|
||
---
|
||
|
||
## Related
|
||
|
||
- [01 – Overview](../01_overview.md) · [02 – Components](../02_components.md) · [01 – Quickstart](01_quickstart.md)
|