# API Contracts and Endpoints

## Overview

This codebase exposes a small set of MVC endpoints that together define the application’s public contracts: HTML views for humans, a JSON resource for veterinarians, and an error-producing endpoint used to validate exception handling. The controllers are tightly scoped and organized by domain area (`owner`, `vet`, and `system`), with each endpoint centered on a single responsibility and backed by repository lookups plus Spring MVC validation and binding rules.

The contract surface is intentionally simple, but it is still important because these endpoints coordinate navigation, form submission, validation errors, redirects, and JSON serialization. The tests in `src/test/java/...` act as executable documentation for those behaviors and make the expected request/response shapes explicit.

## Implementation Patterns

### 1. MVC controllers return either view names or serialized resources

Most controllers are standard `@Controller` classes that return a logical view name after handling a request:

- [OwnerController](../src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java)
- [PetController](../src/main/java/org/springframework/samples/petclinic/owner/PetController.java)
- [VisitController](../src/main/java/org/springframework/samples/petclinic/owner/VisitController.java)
- [WelcomeController](../src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java)
- [CrashController](../src/main/java/org/springframework/samples/petclinic/system/CrashController.java)

The exception is [VetController](../src/main/java/org/springframework/samples/petclinic/vet/VetController.java), which serves both HTML and JSON from the same resource set. The HTML variant returns a view, while the `/vets` endpoint is annotated with `@ResponseBody` and returns a serializable `Vets` wrapper.

### 2. Domain objects are injected through `@ModelAttribute`

The owner-related controllers use `@ModelAttribute` methods to prepare shared request state before request handling:

- `OwnerController` populates an `owner` model attribute from an optional path variable.
- `PetController` loads the current owner, current pet, and available pet types.
- `VisitController` loads the owner, pet, and a fresh `Visit` instance.

This pattern keeps the handler methods focused on contract decisions such as validation, redirects, and view selection rather than manual lookup wiring.

### 3. Binding restrictions protect identifier fields

Each of the mutating controllers configures `WebDataBinder` to disallow `id` and nested `*.id` fields. This prevents clients from overwriting persistence identifiers during form submission and preserves the server-side contract for identity management.

Relevant references:

- [OwnerController](../src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java)
- [PetController](../src/main/java/org/springframework/samples/petclinic/owner/PetController.java)
- [VisitController](../src/main/java/org/springframework/samples/petclinic/owner/VisitController.java)

### 4. Validation is part of the API contract

Form-handling endpoints use Jakarta Validation plus custom checks to define what a valid request looks like:

- Owner creation and update reject invalid owner fields.
- Pet creation and update reject duplicate names and future birth dates.
- Visit creation rejects invalid visit data via validation annotations on `Visit`.
- Error cases return the same form view instead of redirecting, preserving field errors in the model.

The tests make these expectations visible in behavior rather than implementation details:

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

### 5. Redirects communicate success after state changes

Successful create and update operations typically end with a redirect to a canonical read endpoint, along with a flash message. This keeps browser resubmission behavior predictable and establishes a clear post-submit contract.

Examples:

- owner create/update redirects to `/owners/{ownerId}`
- pet create/update redirects to `/owners/{ownerId}`
- visit create redirects to `/owners/{ownerId}`

### 6. Error handling is part of the observable contract

The crash endpoint deliberately throws an exception so the application’s error response can be verified. The integration test checks both JSON and HTML behavior, confirming that the application’s error page and error payload are consistent and do not fall back to the default whitelabel page.

Relevant references:

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

## Key Classes

### [OwnerController](../src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java)
Handles the owner-facing workflow:

- create owner form
- submit new owner
- find owners by last name
- show owner details
- update owner form and submission

It defines the core owner endpoint contract and demonstrates the project’s redirect-plus-flash-message pattern.

### [PetController](../src/main/java/org/springframework/samples/petclinic/owner/PetController.java)
Handles pets nested under an owner path. It is responsible for:

- loading owner-scoped state
- showing the pet form
- creating a pet
- editing pet details

It also shows how business rules become part of the endpoint contract, especially duplicate-name checks and birth-date validation.

### [VisitController](../src/main/java/org/springframework/samples/petclinic/owner/VisitController.java)
Handles nested visit creation for a specific owner and pet. The controller ensures that the owner and pet exist before the visit form is shown or submitted, which makes the request path itself part of the contract.

### [VetController](../src/main/java/org/springframework/samples/petclinic/vet/VetController.java)
Provides two contract surfaces over the same data:

- `/vets.html` for server-rendered HTML
- `/vets` for JSON resources

This dual exposure is important when integrating with browser clients and API consumers simultaneously.

### [WelcomeController](../src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java)
Defines the root endpoint `/` and maps it to the welcome view. It is the simplest contract in the application, but it establishes the landing-page entry point.

### [CrashController](../src/main/java/org/springframework/samples/petclinic/system/CrashController.java)
Intentionally throws a runtime exception at `/oups`. It exists to verify that the application’s error contract behaves correctly and consistently.

## How It Fits Together

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

At a high level, the flow is:

1. The root page (`/`) sends users to the welcome view.
2. Owner routes handle searching, creation, display, and editing.
3. Pet and visit routes extend the owner contract with nested resources.
4. Vet routes expose the same data as either HTML or JSON.
5. The crash route validates how the application responds to exceptions.

## Notes for Developers

- Treat path variables as part of the contract. Nested endpoints depend on valid `ownerId` and, where applicable, `petId` values.
- Preserve binder restrictions when adding new form fields. Do not allow client-supplied identifiers to bypass server-side identity rules.
- When adding new endpoints, decide early whether the contract is view-based, redirect-based, or JSON-based. The controller style should match the intended consumer.
- Keep validation close to the endpoint. Tests should cover both success and failure cases because error views and redirect targets are part of the API behavior.
- Follow the existing repository-backed pattern for nested resources: resolve the parent entity first, then derive the child object from it.
- If you introduce a new external-facing endpoint, add a corresponding `WebMvcTest` that documents the expected view, status code, redirect, or JSON shape.
- Use the existing controller tests as the source of truth for contract expectations:
  - [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)
