# API Contracts and Endpoints

## Overview

This codebase uses Spring MVC controllers as the primary contract boundary for user-facing endpoints and a small set of resource-style responses. The controllers define how requests are mapped, how data is validated and bound, which views are rendered, and how error cases are surfaced.

Across the application, the API surface is intentionally split between:

- browser-oriented HTML endpoints that return template names and populate a `Model`
- a JSON endpoint for veterinarian data via `@ResponseBody`
- a deliberate crash endpoint that exercises the framework’s error-handling contract

The tests in the corresponding `*ControllerTests` classes document these contracts from the outside in, showing expected paths, status codes, view names, validation behavior, and redirect targets.

## Implementation Patterns

### 1. Controllers define the request contract directly

The controllers use Spring annotations such as `@GetMapping`, `@PostMapping`, `@RequestMapping`, and `@PathVariable` to establish endpoint structure and parameter binding.

- [`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) scopes pet operations under `/owners/{ownerId}`.
- [`VisitController`](src/main/java/org/springframework/samples/petclinic/owner/VisitController.java) scopes visit creation under `/owners/{ownerId}/pets/{petId}`.
- [`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java) exposes both HTML and JSON representations.
- [`WelcomeController`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java) provides the landing page.
- [`CrashController`](src/main/java/org/springframework/samples/petclinic/system/CrashController.java) deliberately throws to exercise error responses.

### 2. Validation and data binding are part of the contract

Several controllers protect their inputs with `@Valid`, `BindingResult`, and `WebDataBinder` configuration.

- `OwnerController` and `VisitController` disallow binding to `id` fields to prevent mass-assignment of identifiers.
- `PetController` additionally installs a `PetValidator` and rejects invalid or duplicate pet names.
- `OwnerController` checks for owner ID mismatch on update and returns a flash error if the path and form disagree.
- `PetController` checks duplicate pet names and future birth dates before persisting.
- `VisitController` validates the visit form and returns the same form when errors are present.

These patterns show that the contract is not only the URL structure, but also the allowed fields and acceptable state transitions.

### 3. Redirects and flash messages indicate successful write operations

Write endpoints typically return redirect strings rather than view templates:

- new owner creation redirects to the created owner’s details page
- owner and pet updates redirect back to the owner page
- new pet and new visit flows redirect back to the owner page after saving

Flash attributes communicate success or failure across the redirect boundary, making the request contract explicit for browser flows.

### 4. Repository lookups back the request contract

The controllers use repositories to resolve IDs and hydrate the model:

- `OwnerRepository` powers owner, pet, and visit flows
- `PetTypeRepository` supplies the reference list of pet types
- `VetRepository` supplies vet listings for both HTML and JSON outputs

This means path variables are effectively part of the data-access contract: invalid IDs surface as `IllegalArgumentException`s when objects cannot be found.

### 5. Tests document observable behavior

The controller tests are especially useful as contract examples:

- [`OwnerControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java) verify create, search, update, and detail flows.
- [`PetControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java) verify nested pet routes, validation, and redirect behavior.
- [`VisitControllerTests`](src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java) verify visit creation flows and error handling.
- [`VetControllerTests`](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java) verify both HTML and JSON endpoints.
- [`CrashControllerTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java) and [`CrashControllerIntegrationTests`](src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) verify exception behavior and error page rendering.

## Key Classes

### [`OwnerController`](src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java)
Owner-facing controller that defines the main CRUD-style contract for owners.

Key responsibilities:

- render the owner creation form
- process owner creation
- search owners by last name with pagination
- render owner details
- render and process owner edits

It also establishes the base data-binding rules for owner-related forms.

### [`PetController`](src/main/java/org/springframework/samples/petclinic/owner/PetController.java)
Nested controller for pet operations under an owner.

Key responsibilities:

- provide pet type reference data
- load the owner and optional pet into the model
- render pet create/update forms
- validate pet name uniqueness and birth date constraints
- persist changes back through the owner aggregate

This controller is a good example of a nested resource contract: the owner ID is foundational to every request.

### [`VisitController`](src/main/java/org/springframework/samples/petclinic/owner/VisitController.java)
Nested controller for visit scheduling.

Key responsibilities:

- hydrate owner, pet, and visit before handling requests
- render the visit booking form
- validate and save new visits

The controller treats owner and pet identifiers as required context and rejects requests when either lookup fails.

### [`VetController`](src/main/java/org/springframework/samples/petclinic/vet/VetController.java)
Controller that demonstrates dual representation of the same domain data.

Key responsibilities:

- render a paginated HTML vet list at `/vets.html`
- expose a JSON resource at `/vets`
- package vets in a `Vets` wrapper for easier serialization

This class is the clearest example of a controller with both page-rendering and resource-style contracts.

### [`WelcomeController`](src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java)
Minimal landing-page controller.

Key responsibility:

- map `/` to the `welcome` view

Although simple, it still participates in the endpoint contract by defining the application entry point.

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

Key responsibility:

- map `/oups` and throw a runtime exception

This endpoint exists to validate framework-level error handling and the shape of the resulting error response.

## How It Fits Together

```mermaid
flowchart TD
Overview["PetClinic endpoint contract"] --> OwnerController["OwnerController"]
Overview --> PetController["PetController"]
Overview --> VisitController["VisitController"]
Overview --> VetController["VetController"]
Overview --> WelcomeController["WelcomeController"]
Overview --> CrashController["CrashController"]
OwnerController --> OwnerViews["Owner forms, search, and detail views"]
PetController --> PetViews["Pet create and update views"]
VisitController --> VisitViews["Visit booking view"]
VetController --> VetViews["HTML vet list and JSON vet resource"]
WelcomeController --> WelcomeView["Landing page"]
CrashController --> ErrorHandling["Framework error response and error page"]
```

The flow is straightforward:

1. Requests enter a Spring MVC controller based on URL and HTTP method.
2. Controller methods populate models, validate input, and consult repositories.
3. Successful write operations redirect to a follow-up page.
4. Invalid input returns the same form with binding errors.
5. Exceptions fall through to the framework error handling contract.

## Notes for Developers

- Treat controller mappings as public contracts. Changing a path, redirect target, or response format will affect tests and likely template integration.
- Keep `@InitBinder` restrictions aligned with form models so identifiers cannot be overwritten from the request.
- When adding nested endpoints, follow the existing pattern of resolving parent entities first and failing fast when IDs are invalid.
- Use `BindingResult` immediately after a validated model object so validation errors are captured correctly.
- Prefer redirect-after-post for successful form submissions to avoid duplicate submissions on refresh.
- Add or update controller tests whenever the observable contract changes; the tests are the best executable documentation for these endpoints.
- For any new JSON contract, ensure the serializer shape is intentionally wrapped or flattened, since `VetController` shows that the response object type is part of the API surface.
