A full-stack blogging platform with a Vanilla JS + HTML/CSS frontend and a Spring Boot REST API backend. Authors can register, write posts, manage categories (admin only), and search/browse content seamlessly.
- Tech Stack
- Features
- Use Case Diagram
- ER Diagram
- Data Flow Diagram
- Directory Structure
- API Reference
- Getting Started
- Session Management
- Roles & Permissions
| Layer | Technology |
|---|---|
| Markup | HTML5 |
| Styling | CSS3 (Custom Properties, Flexbox, Grid) |
| Scripting | Vanilla JavaScript (ES6+) |
| HTTP Client | Fetch API |
| Routing | Client-side (hash-based) |
| State | Session Cookie (JSESSIONID) |
| Layer | Technology |
|---|---|
| Framework | Spring Boot 4.0.4 |
| Language | Java 25 |
| Database | MySQL 8 |
| ORM | Spring Data JPA / Hibernate |
| Auth | Session-based (HttpSession) |
| Validation | Jakarta Bean Validation |
| Build Tool | Maven |
- π User registration & session-based login / logout
- π Full CRUD for blog posts with pagination, sorting, and full-text search
- ποΈ Category management β read for all users, write for ADMIN only
- π€ Author profile management with role-based access control
- π Interactive frontend β no framework, pure HTML/CSS/JS
β οΈ Global exception handling with structured error responses
graph TD
Guest([Guest])
User([Authenticated User])
Admin([Admin])
Guest --> UC1[Register]
Guest --> UC2[Login]
Guest --> UC3[Browse Posts]
Guest --> UC4[Search Posts]
Guest --> UC5[View Categories]
User --> UC2
User --> UC6[Logout]
User --> UC7[View My Profile]
User --> UC8[Update My Profile]
User --> UC9[Create Post]
User --> UC10[Update Own Post]
User --> UC11[Delete Own Post]
User --> UC12[View My Posts]
User --> UC3
User --> UC4
User --> UC5
Admin --> UC13[Create Category]
Admin --> UC14[Update Category]
Admin --> UC15[Delete Category]
Admin --> UC16[Delete Any Post]
Admin --> UC17[Delete Any User]
Admin --> UC7
Admin --> UC8
Admin --> UC9
Admin --> UC3
erDiagram
AUTHORS {
BIGINT id PK
VARCHAR name
VARCHAR email UK
VARCHAR password
VARCHAR role
VARCHAR about
}
CATEGORIES {
BIGINT id PK
VARCHAR cat_name UK
VARCHAR description
}
POSTS {
BIGINT id PK
VARCHAR title
LONGTEXT content
DATETIME created_at
BIGINT author_id FK
BIGINT category_id FK
}
AUTHORS ||--o{ POSTS : "writes"
CATEGORIES ||--o{ POSTS : "contains"
graph LR
Client([Client / Browser]) -- HTTP Request --> BlogHub[BlogHub REST API]
BlogHub -- HTTP Response --> Client
BlogHub -- CRUD --> DB[(MySQL Database)]
flowchart TD
Client([Client])
subgraph Frontend
FE[HTML / CSS / JS Pages]
FA[Fetch API Calls]
end
subgraph API Layer
AC[AuthController\n/api/auth]
UC[AuthorController\n/api/users]
CC[CategoryController\n/api/categories]
PC[PostController\n/api/posts]
end
subgraph Middleware
SI[SessionAuthInterceptor\nChecks session & role]
end
subgraph Service Layer
AS[AuthService]
US[AuthorService]
CS[CategoryService]
PS[PostService]
end
subgraph Repository Layer
AR[AuthorRepository]
CR[CategoryRepository]
PR[PostRepository]
end
DB[(MySQL\nbloghub_db)]
Client --> FE --> FA
FA -- "POST /register\nPOST /login" --> AC
FA -- "All other /api/**" --> SI
SI -- "401 if no session\n403 if not ADMIN" --> Client
SI --> UC & CC & PC
AC --> AS
UC --> US
CC --> CS
PC --> PS
AS --> AR
US --> AR
CS --> CR
PS --> PR & AR & CR
AR & CR & PR --> DB
sequenceDiagram
participant B as Browser (JS)
participant AC as AuthController
participant AS as AuthService
participant AR as AuthorRepository
participant DB as MySQL
B->>AC: POST /api/auth/login {email, password}
AC->>AS: login(LoginRequestDto, HttpSession)
AS->>AR: findByEmail(email)
AR->>DB: SELECT * FROM authors WHERE email=?
DB-->>AR: Author row
AR-->>AS: Optional<Author>
AS-->>AS: Validate password match
AS-->>AS: session.setAttribute(userId, role, ...)
AS-->>AC: AuthResponseDto
AC-->>B: 200 OK + Set-Cookie: JSESSIONID
BlogHub/
βββ pom.xml
βββ .mvn/
β βββ wrapper/
β βββ maven-wrapper.properties
βββ src/
βββ main/
β βββ java/com/mardox/bloghub/
β β βββ BlogHubApplication.java # Entry point
β β βββ config/
β β β βββ WebConfig.java # Registers interceptor
β β βββ controller/
β β β βββ AuthController.java # /api/auth
β β β βββ AuthorController.java # /api/users
β β β βββ CategoryController.java # /api/categories
β β β βββ PostController.java # /api/posts
β β βββ dto/
β β β βββ AuthResponseDto.java
β β β βββ AuthorResponseDto.java
β β β βββ AuthorUpdateDto.java
β β β βββ CategoryRequestDto.java
β β β βββ CategoryResponseDto.java
β β β βββ CategoryUpdateDto.java
β β β βββ LoginRequestDto.java
β β β βββ PostRequestDto.java
β β β βββ PostResponseDto.java
β β β βββ PostUpdateDto.java
β β β βββ RegisterRequestDto.java
β β βββ entity/
β β β βββ Author.java # authors table
β β β βββ Category.java # categories table
β β β βββ Post.java # posts table
β β βββ exception/
β β β βββ ErrorResponse.java
β β β βββ GlobalExceptionHandler.java
β β β βββ ResouceAlreadyExistsException.java
β β β βββ ResourceNotFoundException.java
β β βββ interceptor/
β β β βββ SessionAuthInterceptor.java # Auth guard
β β βββ repository/
β β β βββ AuthorRepository.java
β β β βββ CategoryRepository.java
β β β βββ PostRepository.java
β β βββ service/
β β βββ AuthService.java
β β βββ AuthorService.java
β β βββ CategoryService.java
β β βββ PostService.java
β βββ resources/
β βββ static/ # Frontend (HTML/CSS/JS)
β β βββ index.html
β β βββ css/
β β βββ js/
β βββ application.properties
βββ test/
βββ java/com/mardox/bloghub/
βββ BlogHubApplicationTests.java
Base URL: http://localhost:8082
All endpoints except
/api/auth/**require an active session (cookieJSESSIONID).
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
| POST | /api/auth/register |
β | Register a new author |
| POST | /api/auth/login |
β | Login, starts session |
| POST | /api/auth/logout |
β | Invalidate session |
| GET | /api/auth/me |
β | Get current logged-in user |
| Method | Endpoint | Auth Required | Role | Description |
|---|---|---|---|---|
| GET | /api/users |
β | Any | List all authors |
| GET | /api/users/{id} |
β | Any | Get author by ID |
| PUT | /api/users/{id} |
β | Self/Admin | Update author profile |
| DELETE | /api/users/{id} |
β | Self/Admin | Delete author |
| Method | Endpoint | Auth Required | Role | Description |
|---|---|---|---|---|
| GET | /api/categories |
β | Any | List all categories |
| GET | /api/categories/{id} |
β | Any | Get category by ID |
| POST | /api/categories |
β | ADMIN | Create category |
| PUT | /api/categories/{id} |
β | ADMIN | Update category |
| DELETE | /api/categories/{id} |
β | ADMIN | Delete category |
| Method | Endpoint | Auth Required | Role | Description |
|---|---|---|---|---|
| GET | /api/posts |
β | Any | Paginated posts (page, size, sortBy, sortDir) |
| GET | /api/posts/getAll |
β | Any | All posts or search (?term=keyword) |
| GET | /api/posts/{id} |
β | Any | Get post by ID |
| GET | /api/posts/my-post |
β | Any | Get current user's posts |
| POST | /api/posts |
β | Any | Create post |
| PUT | /api/posts/{id} |
β | Self/Admin | Update post |
| DELETE | /api/posts/{id} |
β | Self/Admin | Delete post |
| HTTP Status | Scenario |
|---|---|
| 400 | Validation failure |
| 401 | No active session |
| 403 | Insufficient role (non-admin) |
| 404 | Resource not found / already exists |
| 500 | Unhandled server error |
{
"statusCode": 404,
"errorMessage": "Author not found with id: 5"
}- Java 21+
- Maven 3.9+
- MySQL 8 running locally
1. Clone the repository
git clone https://github.com/neeraj2710/BlogHub.git
cd BlogHub2. Configure the database
Edit src/main/resources/application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/bloghub_db?createDatabaseIfNotExist=true
spring.datasource.username=your_mysql_username
spring.datasource.password=your_mysql_password3. Run the application
./mvnw spring-boot:run4. Open in browser
http://localhost:8082
The database schema is auto-created by Hibernate on first run (
ddl-auto=update).
# Register
curl -c cookies.txt -X POST http://localhost:8082/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Alice","email":"alice@example.com","password":"pass123","about":"Developer"}'
# Login
curl -c cookies.txt -X POST http://localhost:8082/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"alice@example.com","password":"pass123"}'
# Create a post (requires a category to exist first)
curl -b cookies.txt -X POST http://localhost:8082/api/posts \
-H "Content-Type: application/json" \
-d '{"title":"Hello World","content":"My first post.","categoryId":1}'| Attribute | Value |
|---|---|
| Session timeout | 30 minutes |
| Cookie name | JSESSIONID |
| HTTP-only | Yes |
| Same-site | Lax |
Session attributes set on login: userId, userName, userEmail, userRole
| Role | Permissions |
|---|---|
| USER | CRUD own posts Β· Read-only on categories Β· Manage own profile |
| ADMIN | All USER permissions + manage all categories Β· Delete any post or user |