# Schema Separation

Schema separation is a security best practice that's tedious to maintain by hand. Every CRUD API needs separate models for input vs. output to avoid exposing internal fields or allowing clients to set server-managed values. auen enforces this pattern and can auto-derive schemas for prototyping.

## Why not use the table model directly?

Using `Book` as both the request and response model leaks every column to clients and lets them set fields like `id` on creation. This is a common security footgun.

## Explicit schemas (recommended)

```python
from pydantic import BaseModel

class BookCreate(BaseModel):
    title: str
    isbn: str
    author_id: int | None = None

class BookRead(BaseModel):
    id: int
    title: str
    isbn: str
    author_id: int | None = None

class BookUpdate(BaseModel):
    title: str | None = None
    isbn: str | None = None
```

## Auto-derived schemas (quick prototyping)

```python
from auen import derive_schemas

schemas = derive_schemas(Book)
# schemas.create excludes PK fields
# schemas.update makes all non-PK fields optional
# schemas.read includes all fields
```

For nested endpoints, you can derive the full container:

```python
from auen import derive_schema_container

container = derive_schema_container(Book)
# container.nested_update is used by PATCH /{id}/nested
```

Use `derive_schemas`/`derive_schema_container` for prototyping, but define explicit
schemas for production APIs.
