Spring Boot Realworld Example App — Spec vs Reality
Spec source: README.md
Scope: Source code only — infrastructure config files (Docker, CI/CD, YAML) not analysed
Coverage: ██████░░░░ 5/8 features fully implemented, 3 not verifiable from source
Feature Coverage
| Feature | Spec Intent | Code Reality | Status |
|---|---|---|---|
| CRUD Operations | Supports CRUD on articles, comments, users, etc. | Full CRUD via REST controllers and GraphQL mutations. Repositories, services, and mappers for all entities. | ✅ Implemented |
| Authentication with JWT | Spring Security + JWT, secret in properties. | JwtTokenFilter, DefaultJwtService, WebSecurityConfig with JWT filter and BCrypt password encoder. | ✅ Implemented |
| Routing | API endpoints per RealWorld spec. | REST endpoints for articles, comments, users, profiles, tags; also GraphQL. | ✅ Implemented |
| Pagination | Paginated responses for articles. | Cursor-based pagination with direction and extra detection, plus offset-based pagination. | ✅+ Implemented + extras |
| GraphQL Support | GraphQL endpoints using Netflix DGS, schema file. | DGS components for queries and mutations: ArticleDatafetcher, CommentDatafetcher, UserMutation, etc. | ✅ Implemented |
| Database Persistence | Uses SQLite, configurable. | MyBatis mappers and repositories; no SQLite config in source code (only config files). | ~ Too vague to verify |
| Docker Deployment | Docker image via bootBuildImage, container on port 8080→8081. | No build.gradle or Dockerfile in provided source evidence. | ~ Too vague to verify |
| Testing | Many test cases for API and repository layers. | No test source files in provided evidence. | ~ Too vague to verify |
Extended implementations
Pagination — the spec described the basics but the code also: - Supports bi-directional cursor pagination with next/previous - Uses extra item detection to determine more pages
What the code does that the spec never mentioned
These behaviors exist in the codebase but have no entry in any spec document. They represent implicit engineering decisions — security contracts, undocumented constraints, behavioral choices — that the spec author either assumed, forgot, or decided after writing the spec.
1. Bi-Directional Cursor Pagination
Cursor-based pagination supports both next and previous directions with an extra item for hasMore detection. Requires careful cursor ordering.
Evidence: CursorPager.java:L6, CursorPageParameter.java:L7
Why it matters: Enables efficient scrolling but adds complexity in ordering and cursor encoding.
2. Conditional Field Updates
Article.update and User.update only overwrite fields if the new value is non-empty via Util.isEmpty. Empty strings are ignored.
Evidence: Article.java:L51, User.java:L29
Why it matters: Clients expecting empty strings to clear fields will get silent failures.
3. Comprehensive Slug Generation
toSlug replaces ampersands, CJK punctuation, quotes, spaces, punctuation with hyphens, leading to possible multi-hyphen slugs.
Evidence: Article.java:L67
Why it matters: Slugs may become messy or non-unique, affecting URL readability and SEO.
4. Default User Image from Property
New users get a default image from property 'image.default' injected into UserService. If missing, app may crash.
Evidence: UserService.java:L17
Why it matters: Provides consistency but introduces a configuration dependency that could cause failures.
Security Observations
Behaviors with security implications that are not documented in the spec. These are not CVEs — they are undocumented security contracts, auth edge cases, and trust-boundary decisions found directly in the code.
🟡 Permissive CORS Configuration MEDIUM
WebSecurityConfig allows all origins (*) with common methods and headers, disabling credentials. This is excessively permissive.
Evidence: WebSecurityConfig.java:L67-L79
Risk: Allows any website to make cross-origin requests. Although tokens are in Authorization header (not cookies), if a client stores tokens in cookies, it could enable CSRF-like attacks.
Questions for the Engineering Team
- Why is CORS configured to allow all origins instead of specific domains?
- How is the JWT secret managed and rotated in production?
- Is the default user image property ('image.default') set in application.properties? If not, what happens?
- Why are GraphQL endpoints publicly accessible (permitted without authentication)?
- Are there plans to add rate limiting or throttling to prevent abuse?
Generated by Verifiably — every finding is grounded in file:line evidence from the codebase, not training data.