kra-api
REST API for the KRA portfolio: projects and blog backed by DynamoDB, contact form (leads), public GitHub repo listing and repo detail. Write operations on projects and posts require a JWT (Spring OAuth2 resource server, Cognito issuer). Public reads and POST /contact do not require a token.
Stack: Spring Boot 3.5, Java 25, DDD-style layering (domain free of Spring/AWS), AWS SDK v2 (DynamoDB Enhanced Client), GitHub via WebClient, Actuator for health.
Prerequisites
- Java 25 and Maven
- AWS credentials when talking to real DynamoDB (default credential chain)
- Environment variables — see Configuration. Optional
.envat the module root: keys are applied as system properties only if they are not already set in the process environment (existing OS env wins).
Quick Start
- Copy
.env.exampleto.envand set at leastAWS_DYNAMODB_TABLE_NAME,GITHUB_TOKEN,GITHUB_PORTFOLIO_USER, andCOGNITO_ISSUER_URIwhen exercising secured routes locally. - Run:
mvn spring-boot:run - Health:
http://localhost:8080/actuator/health(port overridable withSERVER_PORT).
Commands
| Action | Command |
|---|---|
| Compile | mvn compile |
| Run (default port 8080) | mvn spring-boot:run -Dspring-boot.run.profiles=local |
| Unit / slice tests | mvn test |
Tests + JaCoCo report (target/site/jacoco/index.html) + branch coverage gate (80% on the measured bundle) |
mvn verify |
| Fast domain checks (example) | mvn test -Dtest="ProjectTest,ProjectIdTest" |
| Spring context smoke test | mvn test -Dtest=KraApiApplicationTests |
| Runnable JAR | mvn package -DskipTests → java -jar target/kra-api-0.0.1-SNAPSHOT.jar |
JaCoCo excludes (from coverage rules and Sonar alignment): KraApiApplication, infrastructure.config, infrastructure.repository, infrastructure.github.
Endpoints
Base URL: http://localhost:8080 (override with SERVER_PORT).
| Method | Path | Description | Auth |
|---|---|---|---|
GET |
/projects |
List projects (limit query, default 50, max 100) |
Public |
GET |
/projects/{id} |
Project detail | Public |
POST |
/projects |
Create project | JWT |
PUT |
/projects/{id} |
Update project | JWT |
DELETE |
/projects/{id} |
Delete project | JWT |
GET |
/posts |
List blog posts | Public |
GET |
/posts/{slug} |
Post detail | Public |
POST |
/posts |
Create post | JWT |
PUT |
/posts/{slug} |
Update post | JWT |
DELETE |
/posts/{slug} |
Delete post | JWT |
GET |
/portfolio/repos |
List public repos for the configured GitHub user | Public |
GET |
/portfolio/repos/{owner}/{repo} |
Repo detail (README, topics, languages, …) | Public |
POST |
/contact |
Submit lead (email + message) | Public |
GET |
/actuator/health |
Health check | Public |
Any other path (including other Actuator endpoints) requires authentication per SecurityConfig.
Architecture
flowchart TD
subgraph clients [Clients]
FE[Frontend]
CLI["Tools / admin"]
end
subgraph kra [kra-api]
WEB[Controllers + DTOs]
APP[Application services]
DOM[Domain model + ports]
INFRA[Infra: DynamoDB repos, GitHub client, security, config]
WEB --> APP
APP --> DOM
APP --> INFRA
WEB --> INFRA
end
COG[(Cognito JWT)]
DDB[(DynamoDB)]
GH[GitHub API]
FE -- "Public GET / POST contact" --> WEB
CLI -- "Bearer JWT writes" --> WEB
WEB --> COG
INFRA --> DDB
INFRA --> GH
Full system architecture (C4 Level 1, 2 & 3): kra-docs-architecture
Packages: domain (models + repository interfaces), application (use cases), infrastructure (DynamoDB, HTTP, GitHub, security, configuration). The domain layer does not depend on Spring or the AWS SDK.