Files
is-it-christmas/specs/001-christmas-checker/contracts/api.md
Julien Lengrand-Lambert 16ae2a1430 Creating the project
2025-11-11 10:06:56 +01:00

371 lines
9.0 KiB
Markdown

# API Contract: Christmas Checker
**Date**: 2025-11-11
**Feature**: Christmas Checker Website
**Branch**: 001-christmas-checker
**Version**: 1.0
## Overview
This document defines the REST API contract for the Christmas Checker backend service. The API provides a single endpoint to check if today is Christmas Day.
**Base URL**: `http://localhost:8080` (development), configurable for production
**Protocol**: HTTP/1.1
**Authentication**: None (public API)
**Content-Type**: `application/json`
## Endpoints
### GET /api/christmas
Check if today is Christmas (December 25th or 26th).
**Description**: Returns a boolean indicating whether the current date is Christmas (December 25th or 26th), along with the date that was checked.
#### Request
**Method**: `GET`
**URL**: `/api/christmas`
**Headers**:
- None required
**Query Parameters**: None
**Request Body**: None
**Example Request**:
```http
GET /api/christmas HTTP/1.1
Host: localhost:8080
```
#### Response
**Success Response**:
**Status Code**: `200 OK`
**Headers**:
- `Content-Type: application/json`
- `Access-Control-Allow-Origin: *` (CORS support)
**Response Body Schema**:
```json
{
"isChristmas": boolean,
"date": "YYYY-MM-DD"
}
```
**Fields**:
- `isChristmas` (boolean, required): `true` if today is December 25th or 26th, `false` otherwise
- `date` (string, required): The current date in ISO 8601 format (YYYY-MM-DD)
**Example Response (Not Christmas)**:
```http
HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: *
```
**Example Response (Christmas - Dec 25)**:
```http
HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: *
```
**Example Response (Christmas - Dec 26)**:
```http
HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: *
```
#### Error Responses
**500 Internal Server Error**:
Returned when the server cannot determine the current date or encounters an unexpected error.
**Status Code**: `500 Internal Server Error`
**Response Body**:
```json
{
"error": "Unable to determine current date",
"message": "string describing the error"
}
```
**Example**:
```http
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
```
**405 Method Not Allowed**:
Returned when using any HTTP method other than GET.
**Status Code**: `405 Method Not Allowed`
**Allowed Methods**: GET
**Example**:
```http
HTTP/1.1 405 Method Not Allowed
Allow: GET
```
## CORS Policy
**Access-Control-Allow-Origin**: `*` (all origins allowed)
**Rationale**: This is a public API with no sensitive data. Allowing all origins enables the frontend to be hosted on any domain.
**Preflight Requests** (OPTIONS):
For CORS preflight requests, the server responds with:
```http
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
```
## Response Timing
**Expected Response Time**: < 100ms (typically < 10ms)
**Rationale**: Simple date comparison with no I/O operations or external dependencies.
## Caching
**Cache-Control**: `no-cache, no-store, must-revalidate`
**Rationale**: The response changes daily at midnight, so aggressive caching would serve stale data. Clients should re-check the date on each page load.
**Alternative Strategy**: Could cache for up to 1 hour with:
```
Cache-Control: max-age=3600
```
But `no-cache` is safer to ensure users always see current date.
## Rate Limiting
**Rate Limit**: None
**Rationale**: The endpoint is stateless and computationally trivial. No rate limiting needed for this simple use case.
## API Versioning
**Version**: 1.0 (embedded in this document)
**Versioning Strategy**: For future changes:
- **Non-breaking changes** (e.g., adding optional fields): No version change needed
- **Breaking changes** (e.g., changing response schema): Introduce `/v2/api/christmas` endpoint
**Current Commitment**: No breaking changes planned. Schema is stable.
## Client Usage Examples
### JavaScript (Fetch API)
```javascript
// Check if it's Christmas
async function checkChristmas() {
try {
const response = await fetch('http://localhost:8080/api/christmas');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
if (data.isChristmas) {
console.log("🎄 It's Christmas!");
// Show snow animation
} else {
console.log("☹️ Not Christmas yet...");
// Show sad smiley
}
console.log(`Checked date: ${data.date}`);
} catch (error) {
console.error('Failed to check Christmas status:', error);
// Fall back to client-side date check
}
}
checkChristmas();
```
### cURL
```bash
# Check Christmas status
curl -X GET http://localhost:8080/api/christmas
# Pretty-print JSON response
curl -X GET http://localhost:8080/api/christmas | jq
```
### Java (HttpClient)
```java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/api/christmas"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
// Parse JSON response
String json = response.body();
// Use JSON library or manual parsing
}
```
## Testing Contract
### Contract Tests
The following tests should verify contract compliance:
1. **Response Status**: GET /api/christmas returns 200 OK
2. **Response Content-Type**: Header is `application/json`
3. **Response Schema**: Body contains `isChristmas` (boolean) and `date` (string)
4. **Date Format**: `date` field matches ISO 8601 format (YYYY-MM-DD)
5. **Christmas Logic**: On December 25th or 26th, `isChristmas` is `true`
6. **Non-Christmas Logic**: On any other date, `isChristmas` is `false`
7. **CORS Headers**: Response includes `Access-Control-Allow-Origin: *`
8. **Method Not Allowed**: POST/PUT/DELETE return 405 or appropriate error
### Sample Contract Test (Pseudocode)
```
Test: ChristmasEndpointContract
Given: Server is running
When: GET /api/christmas
Then:
- Status code is 200
- Content-Type is application/json
- Response body has field "isChristmas" (boolean)
- Response body has field "date" (string matching YYYY-MM-DD)
- CORS header Access-Control-Allow-Origin is "*"
Test: ChristmasLogicOnChristmasDay
Given: Server system date is December 25th or 26th
When: GET /api/christmas
Then:
- Response isChristmas is true
- Response date ends with "-12-25" or "-12-26"
Test: ChristmasLogicOnNonChristmasDay
Given: Server system date is NOT December 25th or 26th
When: GET /api/christmas
Then:
- Response isChristmas is false
- Response date does NOT end with "-12-25" or "-12-26"
```
## OpenAPI Specification (Swagger)
```yaml
openapi: 3.0.3
info:
title: Christmas Checker API
description: Check if today is Christmas Day
version: 1.0.0
servers:
- url: http://localhost:8080
description: Development server
paths:
/api/christmas:
get:
summary: Check if today is Christmas
description: Returns whether the current date is December 25th or 26th
operationId: checkChristmas
responses:
'200':
description: Successful response
headers:
Access-Control-Allow-Origin:
schema:
type: string
example: "*"
content:
application/json:
schema:
type: object
required:
- isChristmas
- date
properties:
isChristmas:
type: boolean
description: True if today is December 25th or 26th
example: false
date:
type: string
format: date
description: Current date in ISO 8601 format
example: "2025-11-11"
'500':
description: Internal server error
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Unable to determine current date"
message:
type: string
example: "System clock unavailable"
```
## Change Log
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2025-11-11 | Initial API contract definition |
## Notes
- **Client-Side Alternative**: Frontend can check the date client-side using JavaScript `Date()` object, making this API endpoint optional for core functionality
- **Timezone Handling**: Server uses its local timezone. For production, consider UTC or accepting timezone parameter
- **Future Enhancements**: Could add query parameter `?tz=America/New_York` to check Christmas in specific timezone