# API Contracts and Endpoints

## Overview

This codebase exposes a small set of HTTP endpoints built with Spring MVC controllers. Most of them render HTML views and exchange form data, while one controller also exposes a JSON resource representation for veterinarians. The overall contract style is intentionally simple:

- request mappings are defined close to the controller that owns the workflow
- form submissions are validated server-side before persistence
- redirects are used after successful POSTs to preserve the Post/Redirect/Get pattern
- shared model objects are loaded with `@ModelAttribute` methods so nested routes can reuse the same owner and pet context
- error behavior is part of the contract, especially for the crash endpoint used to demonstrate application failure handling

This matters because the controllers define how the application is consumed by both browsers and clients that read JSON. The tests in the codebase act as executable contract checks for those endpoints.

## Implementation Patterns

### HTML-first controller design

Most endpoints return view names rather than serialized payloads. That is visible in the main controllers:

- [`WelcomeController`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java) maps `/` to the `welcome` view.
- [`OwnerController`](src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java) handles owner search, creation, update, and detail pages.
- [`PetController`](src/main/java/org/springframework/samples/petclinic/owner/PetController.java) manages pet creation and updates inside an owner-centric route.
- [`VisitController`](src/main/java/org/springframework/samples/petclinic/owner/VisitController.java) handles visit booking beneath a pet route.
- [`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java) serves both HTML and JSON representations of veterinarians.

The controllers are annotated with `@Controller`, and their methods usually return view names or redirects. The tests confirm that behavior by checking view names, status codes, and model attributes.

### Route-centric ownership of contracts

The endpoint structure encodes the domain relationship:

- owners are top-level resources at `/owners`
- pets are nested under `/owners/{ownerId}/pets`
- visits are nested under `/owners/{ownerId}/pets/{petId}/visits`
- veterinarians are available at `/vets` and `/vets.html`
- the demo failure endpoint is `/oups`

That nesting is not just cosmetic. The child controllers use `@ModelAttribute` methods to load the parent owner and the current pet or visit before the request handler runs. For example, [`PetController`](src/main/java/org/springframework/samples/petclinic/owner/PetController.java) and [`VisitController`](src/main/java/org/springframework/samples/petclinic/owner/VisitController.java) both load the owner from `OwnerRepository` so the request always operates in the correct aggregate context.

### Validation and binding rules are part of the API contract

The controllers actively protect their inputs:

- `@InitBinder` disables binding to `id` and nested `*.id` fields in owner, pet, and visit flows
- `PetController` adds a `PetValidator` for pet submissions
- `OwnerController` and `PetController` reject mismatched IDs when the path and form data do not line up
- form handlers validate `@Valid` objects and return the form view again when validation fails

This means the contract is not just the URL pattern. It also includes what inputs are accepted, what gets rejected, and which error view is shown when validation fails.

### Pagination and list models are standardized

Both the owner and vet list screens use paginated results with a common model shape:

- `currentPage`
- `totalPages`
- `totalItems`
- collection attribute such as `listOwners` or `listVets`

See [`OwnerController`](src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java) and [`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java). This shared pattern keeps the list views predictable and makes pagination behavior consistent across the app.

### Dual representation for veterinarian data

[`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java) is the one controller that exposes both an HTML page and a machine-readable resource:

- `/vets.html` returns the `vets/vetList` view for browser rendering
- `/vets` returns a `Vets` object as JSON via `@ResponseBody`

This is the clearest example in the codebase of an endpoint with multiple representations sharing the same underlying repository data.

### Error handling is explicit for the crash endpoint

[`CrashController`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java) deliberately throws a runtime exception from `/oups`. The integration tests show that the application’s error contract matters in both JSON and HTML modes. This endpoint is not meant for business logic; it exists to verify the error response path and the custom error page.

## Key Classes

### [`WelcomeController`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java)

Entry-point controller for `/`. It provides the simplest route contract in the application and returns the landing page view.

### [`OwnerController`](src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java)

Owns the main owner workflow:

- create owner
- search owners
- list owners with pagination
- edit owner
- show owner details

It also demonstrates the strongest request-contract rules in the app, including allowed-field restrictions, form validation, redirect behavior, and ID mismatch handling.

### [`PetController`](src/main/java/org/springframework/samples/petclinic/owner/PetController.java)

Owns nested pet routes beneath a specific owner. It shows how the codebase models hierarchical resources and how child entities are loaded and validated in the context of their parent owner.

### [`VisitController`](src/main/java/org/springframework/samples/petclinic/owner/VisitController.java)

Owns visit booking beneath a pet. It preloads both owner and pet context, then adds a visit and persists through the owner aggregate. This controller demonstrates how the app enforces parent-child relationships at the HTTP layer.

### [`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java)

Exposes veterinarian lists in two forms: HTML and JSON. It is the primary example of a controller that supports both browser consumption and external API-style consumption from the same endpoint family.

### [`CrashController`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java)

A deliberately failing controller used to validate application error responses. It defines the contract for what happens when request processing throws an exception.

## How It Fits Together

```mermaid
flowchart TD
A["WelcomeController - /"] --> B["welcome view"]
C["OwnerController - /owners"] --> D["OwnerRepository"]
E["PetController - /owners/{ownerId}/pets"] --> D
F["VisitController - /owners/{ownerId}/pets/{petId}/visits"] --> D
G["VetController - /vets and /vets.html"] --> H["VetRepository"]
I["CrashController - /oups"] --> J["error handling"]
```

The flow is intentionally layered:

1. Browser requests start at a controller route.
2. The controller loads domain state from a repository, often using `@ModelAttribute` to prepare shared data.
3. The handler returns either a view name, a redirect, or a JSON body.
4. Validation failures return the same form view with model errors.
5. Exceptions route into the application’s error handling path.

The tests in the codebase exercise these flows as endpoint contracts rather than only unit-level method behavior.

## Notes for Developers

- Keep route ownership aligned with the domain aggregate. Owner, pet, and visit routes are nested for a reason.
- If you add a new endpoint, decide up front whether it is HTML, JSON, or both.
- Treat binder restrictions as part of the public contract. If you relax them, review the security and data-binding implications.
- Preserve redirect targets after successful POSTs so form submissions remain idempotent from the user’s perspective.
- When adding new list pages, follow the pagination model pattern used by owner and vet lists.
- If you change error handling behavior, update the crash endpoint tests because they codify the expected failure response.
- Use the existing tests as a reference for acceptable request parameters, validation behavior, and expected status codes.

## Related Contract Tests

These tests are the clearest executable documentation for endpoint behavior:

- [`OwnerControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java)
- [`PetControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java)
- [`VisitControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java)
- [`VetControllerTests`](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java)
- [`CrashControllerTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java)
- [`CrashControllerIntegrationTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java)
