> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Hypermedia

> Hypermedia response helpers for HATEOAS APIs.

## Overview

The `hypermedia` middleware provides helpers for building HATEOAS (Hypermedia as the Engine of Application State) APIs with links and embedded resources.

Use it when you need:

* RESTful hypermedia APIs
* Self-documenting responses
* Discoverable APIs

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/hypermedia"
```

## Quick Start

```go theme={null}
app := mizu.New()

app.Use(hypermedia.New())

app.Get("/users/:id", func(c *mizu.Ctx) error {
    user := getUser(c.Param("id"))

    return hypermedia.JSON(c, 200, user,
        hypermedia.Self("/users/"+user.ID),
        hypermedia.Link("orders", "/users/"+user.ID+"/orders"),
    )
})
```

## Configuration

### Options

| Option    | Type     | Default | Description        |
| --------- | -------- | ------- | ------------------ |
| `BaseURL` | `string` | `""`    | Base URL for links |
| `Format`  | `string` | `"hal"` | HAL or JSON:API    |

## Examples

### HAL Format

```go theme={null}
app.Get("/users/:id", func(c *mizu.Ctx) error {
    return hypermedia.HAL(c, 200, user,
        hypermedia.Self("/users/1"),
        hypermedia.Link("orders", "/users/1/orders"),
    )
})
// {
//   "id": 1,
//   "name": "John",
//   "_links": {
//     "self": {"href": "/users/1"},
//     "orders": {"href": "/users/1/orders"}
//   }
// }
```

### Embedded Resources

```go theme={null}
app.Get("/users/:id", func(c *mizu.Ctx) error {
    return hypermedia.HAL(c, 200, user,
        hypermedia.Self("/users/1"),
        hypermedia.Embed("orders", orders),
    )
})
```

### Collection with Pagination

```go theme={null}
app.Get("/users", func(c *mizu.Ctx) error {
    return hypermedia.Collection(c, 200, users,
        hypermedia.Self("/users"),
        hypermedia.Link("next", "/users?page=2"),
        hypermedia.Link("prev", "/users?page=0"),
    )
})
```

## API Reference

### Functions

```go theme={null}
// New creates hypermedia middleware
func New() mizu.Middleware

// HAL returns HAL+JSON response
func HAL(c *mizu.Ctx, status int, data any, links ...Link) error

// Collection returns HAL collection
func Collection(c *mizu.Ctx, status int, items any, links ...Link) error

// Link helpers
func Self(href string) Link
func Link(rel, href string) Link
func Embed(rel string, data any) Link
```

## Technical Details

### Architecture

The hypermedia middleware uses a response recorder pattern to intercept and modify JSON responses:

1. **Context Storage**: Links are stored in the request context using a private context key
2. **Response Recording**: A custom `responseRecorder` captures the response body and status code
3. **JSON Modification**: The middleware parses the JSON response, injects links, and re-encodes it
4. **Content-Type Filtering**: Only processes responses with `application/json` content type

### Implementation Details

**Link Structure**:

* `Href`: The URL of the linked resource
* `Rel`: The relationship type (e.g., "self", "next", "prev")
* `Method`: Optional HTTP method for the link
* `Title`: Optional human-readable description
* `Type`: Optional media type hint

**Response Recorder**:
The middleware implements a custom `responseRecorder` that wraps the original `http.ResponseWriter` to:

* Capture response body in a buffer
* Record status code
* Allow modification before final write

**HAL+JSON Support**:
The `HAL` type provides full HAL+JSON specification support with:

* Properties for resource data
* Links map for hypermedia links
* Embedded map for nested resources
* Custom JSON marshaling to flatten properties into the root object

### Performance Considerations

* Links are stored as pointers in context to avoid copying
* JSON parsing only occurs for `application/json` responses
* Non-JSON responses pass through without modification
* Response buffering adds minimal overhead

### Security Considerations

* Base URL validation prevents injection attacks
* Links are added server-side, not from user input
* TLS detection for automatic scheme selection
* No sensitive data should be exposed in link URLs

## Best Practices

* Always include self link
* Use consistent link relations
* Document link relations
* Consider client library support

## Testing

The hypermedia middleware includes comprehensive test coverage for all functionality:

| Test Case                 | Description                          | Expected Behavior                                                                            |
| ------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------- |
| `TestNew`                 | Basic middleware initialization      | Creates middleware with default options and adds self link to JSON response                  |
| `TestSelfLink`            | Self link generation with base URL   | Automatically adds self link with correct base URL and rel="self"                            |
| `TestAddLink`             | Adding single link to response       | Successfully adds custom link to response links array                                        |
| `TestAddLinks`            | Adding multiple links at once        | Adds multiple links in a single call to the response                                         |
| `TestLinkProvider`        | Dynamic link generation via provider | Invokes link provider function to generate context-aware links                               |
| `TestNonJSONResponse`     | Non-JSON response handling           | Passes through non-JSON responses unchanged without adding links                             |
| `TestCustomLinksKey`      | Custom links key configuration       | Uses custom key instead of default "\_links" for link storage                                |
| `TestResource`            | Resource wrapper with links          | Creates resource structure with data and links fields                                        |
| `TestCollection`          | Paginated collection with links      | Generates collection with pagination metadata and navigation links (first, prev, next, last) |
| `TestCollectionFirstPage` | First page pagination                | Omits "prev" link on first page of results                                                   |
| `TestCollectionLastPage`  | Last page pagination                 | Omits "next" link on last page of results                                                    |
| `TestHAL`                 | HAL+JSON resource creation           | Creates HAL resource with properties and links, marshals correctly                           |
| `TestHALEmbedded`         | HAL embedded resources               | Embeds related resources within HAL response structure                                       |
| `TestGetLinks`            | Retrieving current links             | Returns current links from context during request handling                                   |

## Related Middlewares

* [envelope](/middlewares/envelope) - Response wrapping
* [version](/middlewares/version) - API versioning
