Spring Boot implementation of a design-first, HATEOAS-enabled meeting scheduler (doodle-like) based on the OpenAPI spec.
- Design-first OpenAPI (
openapi/openapi.yaml, served asstatic/openapi.yaml). - Thin controller delegating to service/mappers; endpoints: create/list meetings, add/remove slots, submit votes, get summary.
- HATEOAS:
Linkheaders and_linksin bodies for meetings and slots. - Integration tests:
- MockMvc happy paths, HATEOAS assertions, and 404 cases.
- Client-stub end-to-end test using generated Java client (
ClientStubsIntegrationTest).
cd server
mvn spring-boot:run
# defaults to server.port=7878 (see application.properties)Swagger UI: http://localhost:7878/swagger-ui/index.html (served from static/openapi.yaml).
cd server
mvn testIncludes MockMvc ITs and the generated-client IT.
Client generated into client/ via openapi-generator-cli (7.6.0). If you regenerate:
openapi-generator-cli generate \
-g java \
-i server/src/main/resources/static/openapi.yaml \
-o client \
--api-package org.openapitools.client.api \
--model-package org.openapitools.client.model \
--artifact-id meeting-client \
--group-id org.openapitools \
--additional-properties=library=resttemplate,dateLibrary=java8
mvn -f client/pom.xml clean installThen ensure server/pom.xml has the test-scoped dependency on meeting-client.
# create meeting
curl -i -X POST http://localhost:7878/meetings \
-H "Content-Type: application/json" \
-d '{ "title": "Project Sync" }'
# add slot (replace MEETING_ID)
curl -i -X POST http://localhost:7878/meetings/MEETING_ID/slots \
-H "Content-Type: application/json" \
-d '{ "startTime": "2025-01-10T10:00:00Z", "endTime": "2025-01-10T11:00:00Z" }'
# vote (replace MEETING_ID, SLOT_ID)
curl -i -X POST http://localhost:7878/meetings/MEETING_ID/votes \
-H "Content-Type: application/json" \
-d '[{ "slotId": "SLOT_ID", "user": "Alice", "availability": "true" }]'
# summary
curl -i http://localhost:7878/meetings/MEETING_ID/summary