# API Contracts and Endpoints

## Overview

This codebase exposes a small set of Spring MVC endpoints that act as the primary API surface for the application. Most controllers render server-side views, while a few also expose JSON contracts for programmatic access. The result is a mixed web API: HTML forms and pages for user workflows, plus a lightweight REST-style endpoint for vets and a dedicated failure endpoint for error handling demonstrations.

The main contract boundaries are:

- request mappings and path variables that shape how resources are addressed
- model binding and validation rules that define what payloads are accepted
- redirect and flash-message conventions that define post-submit behavior
- JSON serialization for the vet listing endpoint
- error propagation and error-page behavior for the crash endpoint

## Implementation Patterns

### Controller-driven HTTP contracts

The controllers define endpoint contracts directly with Spring annotations rather than through a separate interface layer. Each controller owns a narrow slice of the URL space and couples request mapping with view selection, binding, and validation.

Examples:

- [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 display endpoints under `/owners`.
- [PetController](../src/main/java/org/springframework/samples/petclinic/owner/PetController.java) handles nested pet workflows under `/owners/{ownerId}`.
- [VisitController](../src/main/java/org/springframework/samples/petclinic/owner/VisitController.java) handles nested visit creation under `/owners/{ownerId}/pets/{petId}`.
- [VetController](../src/main/java/org/springframework/samples/petclinic/vet/VetController.java) serves both HTML and JSON representations of veterinarians.
- [CrashController](../src/main/java/org/springframework/samples/petclinic/system/CrashController.java) provides a deliberate exception path at `/oups`.

### HTML-first endpoints with explicit redirects

The owner, pet, visit, and vet HTML endpoints follow a conventional server-rendered pattern:

1. GET endpoints load model state and return a view name.
2. POST endpoints validate submitted form data.
3. Successful form submissions redirect to a canonical resource page.
4. Validation failures re-render the original form view.

This pattern is visible in the tests:

- [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)

### Nested resource modeling

The owner domain is modeled as a hierarchy of nested resources:

- owners can be created, searched, updated, and viewed directly
- pets belong to a specific owner and are addressed through `/owners/{ownerId}/pets/...`
- visits belong to a specific pet and are addressed through `/owners/{ownerId}/pets/{petId}/visits/...`

This nesting is enforced at the controller level through `@PathVariable`-backed model loading and through repository lookups before form processing.

### Binding and validation safeguards

The controllers consistently guard against unsafe or invalid form submission:

- `WebDataBinder` disallows binding to `id` fields and nested `*.id` fields.
- `@Valid` triggers bean validation on submitted domain objects.
- Additional domain checks catch conditions such as duplicate pet names, future birth dates, and owner ID mismatches.
- Missing owner or pet records are surfaced as `IllegalArgumentException` failures.

The tests demonstrate these rules as part of the observable contract, not just as internal implementation details.

### Dual representation for vets

[VetController](../src/main/java/org/springframework/samples/petclinic/vet/VetController.java) exposes both:

- `/vets.html` for HTML rendering with pagination metadata
- `/vets` for JSON output using `@ResponseBody`

This makes the controller a useful example of one resource with two presentation contracts.

### Error contract demonstration

[CrashController](../src/main/java/org/springframework/samples/petclinic/system/CrashController.java) intentionally throws an exception from `/oups`. The corresponding tests show how the application renders error responses in both JSON and HTML modes:

- [CrashControllerTests](../src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java)
- [CrashControllerIntegrationTests](../src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java)

## Key Classes

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

Serves the application home page. It is the simplest endpoint in the codebase and establishes the baseline contract for a view-only controller.

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

Owns the main owner-facing workflow:

- `/owners/new` for create forms and submissions
- `/owners/find` for the search form
- `/owners` for search results and broad listing behavior
- `/owners/{ownerId}` for owner detail pages
- `/owners/{ownerId}/edit` for owner updates

It also demonstrates several contract concerns at once: input sanitization, validation, error propagation, flash messaging, pagination, and redirect behavior.

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

Owns pet lifecycle operations within the owner aggregate:

- `/owners/{ownerId}/pets/new`
- `/owners/{ownerId}/pets/{petId}/edit`

The controller loads both owner and pet context before handling requests, which keeps the endpoint contract tied to the parent resource. It also enforces business rules around duplicate names and valid birth dates.

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

Owns visit creation under a specific owner and pet. It preloads the pet into the model, ensures the owner and pet exist, and persists visits through the owning aggregate. The contract is intentionally narrow: the controller only supports new visit creation and no standalone visit listing or update API.

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

Serves both the HTML vet list and the JSON vet resource collection. It also shows the pagination contract for the HTML view, including current page, total pages, total items, and the current page slice.

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

A dedicated failure endpoint used to exercise error handling behavior. It is not a business API endpoint; it exists so the application’s exception and error-page contracts can be verified.

## How It Fits Together

The endpoints fit together as a layered web contract centered on the owner aggregate and its child resources.

```mermaid
flowchart TD
A["WelcomeController"] --> B["Home page /"]
C["OwnerController"] --> D["Owner search and details"]
C --> E["Owner create and update forms"]
F["PetController"] --> G["Pet create and update under /owners/{ownerId}"]
H["VisitController"] --> I["Visit create under /owners/{ownerId}/pets/{petId}"]
J["VetController"] --> K["HTML vets list /vets.html"]
J --> L["JSON vets list /vets"]
M["CrashController"] --> N["Error demo endpoint /oups"]
```

In practical terms:

- users enter through the welcome page
- owner workflows anchor the rest of the application
- pet and visit endpoints depend on owner and pet context already being resolved
- vet data is available both as HTML and JSON
- crash handling is isolated so the error contract can be validated independently

## Notes for Developers

- Treat controller mappings as part of the public contract. Changing paths, view names, or redirect targets will usually require test updates and can break browser flows.
- Keep nested resource ownership intact. Pet and visit endpoints should continue to require their parent IDs so that lookups remain scoped correctly.
- Preserve binder restrictions on `id` fields. These are an important defense against over-posting and accidental identity changes.
- Validation behavior is part of the contract. If you add new fields or rules, update both the controller logic and the MVC tests that assert the resulting errors.
- Use flash attributes consistently for success and failure messaging when redirecting after form submissions.
- If you add new JSON endpoints, follow the vet controller pattern by documenting the response shape in tests as well as in the controller.
- The crash endpoint is intentionally pathological. Do not reuse it for normal application flow; it exists to protect and demonstrate the error-response contract.
- When introducing new endpoints, prefer matching the existing style: a focused controller, a narrow URL namespace, and tests that lock down both status codes and view or payload shape.
