FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Echo_Script/backend at main · aminehabchi/Echo_Script · GitHub

Latest commit

 

History

History

README.md

Backend - Social Blogging Platform API

A robust RESTful API built with Spring Boot 3.5, featuring JWT authentication, real-time WebSocket communication, and comprehensive content management capabilities.

Table of Contents

Technologies

Core Framework & Language

  • Spring Boot: 3.5.6 - Enterprise-grade Java application framework
    • Auto-configuration for rapid development
    • Production-ready features (metrics, health checks)
    • Embedded server support
  • Java: 17 - Long-term support (LTS) version
    • Record classes
    • Pattern matching
    • Text blocks
    • Sealed classes
  • Maven: 3.9.3 - Build automation and dependency management
    • POM-based project configuration
    • Dependency resolution
    • Plugin ecosystem

Web & REST API

  • Spring Boot Starter Web - RESTful web services
    • Spring MVC for request handling
    • Jackson for JSON serialization/deserialization
    • RESTful API design patterns
    • Content negotiation
  • Embedded Tomcat - Servlet container (via Spring Boot)
    • Port 8080 by default
    • Session management
    • Thread pool configuration
  • Spring Boot Starter Validation - Bean validation
    • Hibernate Validator implementation
    • JSR-380 Bean Validation 2.0
    • Custom constraint annotations
  • SpringDoc OpenAPI: 2.8.14 - API documentation
    • Swagger UI interface at /swagger-ui.html
    • OpenAPI 3.0 specification
    • Interactive API testing
    • Automatic endpoint discovery

Database & ORM

  • PostgreSQL: 18 - Advanced open-source relational database
    • ACID compliance
    • JSON/JSONB support
    • Full-text search
    • Advanced indexing
  • PostgreSQL JDBC Driver - Database connectivity
    • Type 4 pure Java driver
    • Connection pooling support
  • Spring Boot Starter Data JPA - Java Persistence API
    • Repository abstraction
    • Query methods
    • Transaction management
    • Pagination and sorting
  • Hibernate ORM: 6.6+ - Object-relational mapping framework
    • Entity management
    • Lazy loading
    • Caching (first and second level)
    • HQL (Hibernate Query Language)
  • Flyway Core - Database version control
    • SQL-based migrations
    • Versioned schema management
    • Rollback support
    • Baseline migrations
  • Flyway PostgreSQL - PostgreSQL-specific Flyway support
    • PostgreSQL data types
    • PostgreSQL-specific SQL syntax

Caching Layer

  • Redis: latest - In-memory data structure store
    • Sub-millisecond latency
    • Key-value storage
    • Pub/Sub messaging
    • Persistence options
  • Spring Data Redis: 3.2.0 - Spring integration for Redis
    • RedisTemplate for operations
    • Cache abstraction support
    • Automatic serialization
    • Repository support
  • Jedis: 5.1.2 - High-performance Redis Java client
    • Thread-safe connection pooling
    • Pipelining support
    • Cluster and Sentinel support
    • Blocking and non-blocking operations

Security & Authentication

  • Spring Boot Starter Security - Security framework
    • Authentication and authorization
    • CSRF protection
    • Session management
    • Security filters chain
    • Method-level security (@PreAuthorize, @Secured)
  • JWT (JJWT): 0.11.5 - JSON Web Token implementation
    • jjwt-api: 0.11.5 - JWT API interfaces
    • jjwt-impl: 0.11.5 - JWT implementation
    • jjwt-jackson: 0.11.5 - Jackson integration for JSON processing
    • HS256 signature algorithm
    • Token generation and validation
    • Claims-based authentication
  • BCrypt - Password hashing algorithm (via Spring Security)
    • Adaptive hashing with configurable rounds
    • Salt generation
    • Protection against rainbow table attacks

Real-Time Communication

  • Spring Boot Starter WebSocket - WebSocket support
    • Full-duplex communication
    • SockJS fallback support
    • STOMP protocol integration
    • Message broker configuration
  • STOMP Protocol - Simple Text Oriented Messaging Protocol
    • Text-based messaging
    • Frame-based message structure
    • Destination-based routing
    • Subscription management
  • SockJS - WebSocket fallback library
    • Cross-browser compatibility
    • Automatic fallback transports
    • Connection lifecycle management

JSON Processing

  • Jackson Datatype JSR310: 2.20.1 - Java 8 Date/Time API support
    • LocalDate, LocalDateTime serialization
    • ISO-8601 format support
    • Timezone handling
  • Jackson Datatype Hibernate5: 2.20.1 - Hibernate integration
    • Lazy-loaded entity handling
    • Proxy object serialization
    • Prevents infinite recursion in bidirectional relationships

Development Utilities

  • Lombok: 1.18.32 - Code generation and boilerplate reduction
    • @Data, @Getter, @Setter annotations
    • @Builder for fluent object creation
    • @Slf4j for logging
    • @AllArgsConstructor, @NoArgsConstructor
    • Reduces boilerplate by ~40%

Testing Framework

  • JUnit Jupiter: 5.9.2 - Modern testing framework for Java
    • @Test, @BeforeEach, @AfterEach annotations
    • Parameterized tests
    • Test lifecycle management
    • Nested test classes
    • Assertions and assumptions
  • REST Assured: 5.3.1 - REST API testing library
    • Fluent BDD-style syntax (given/when/then)
    • JSON/XML validation
    • Request/response specification
    • Authentication support
    • Schema validation
  • Spring Boot Starter Test - Testing utilities
    • JUnit 5 integration
    • Spring Test Context framework
    • MockMvc for controller testing
    • @SpringBootTest for integration tests
    • @DataJpaTest for repository testing
    • AssertJ for fluent assertions
    • Mockito for mocking

Build Tools & Plugins

  • Spring Boot Maven Plugin: 3.3.2 - Spring Boot build integration
    • Executable JAR/WAR packaging
    • Repackaging dependencies
    • Build information generation
    • Application lifecycle management

Containerization & Deployment

  • Docker - Container platform
    • Multi-stage Dockerfile for optimized images
    • Layer caching for faster builds
  • Docker Compose: 3.9 - Multi-container orchestration
    • Service dependencies management
    • Health checks
    • Environment variables configuration
  • Eclipse Temurin: 17-jdk - OpenJDK distribution
    • Free, open-source JDK
    • Long-term support
    • Production-ready

Features

Authentication & Authorization

  • JWT-based authentication
  • OAuth2 integration (Google, GitHub, Facebook)
  • Basic Auth for login endpoint
  • BCrypt password encryption
  • Session management (hybrid JWT + HTTP sessions)
  • Role-based access control (USER, ADMIN)
  • Multi-filter authentication chain

User Management

  • User registration and login
  • Profile management
  • Avatar upload and storage
  • User ban system (admin)
  • Followers/following system
  • Friend list (mutual follows)
  • Online/offline status tracking

Content Management

  • Posts

    • Create, read, update, delete posts
    • Rich content with banner images
    • Category tagging
    • Post visibility control
    • Save/bookmark posts
    • Search and filtering
    • Post likes/interactions
  • Comments

    • Nested comment structure (parent-child relationships)
    • Comment on posts
    • Reply to comments
    • Comment likes/interactions
    • Delete comments

Social Features

  • Follow/unfollow users
  • Like posts and comments
  • Save posts for later
  • User profiles with stats
  • Follower/following lists
  • Friend discovery

Real-Time Features

  • WebSocket Communication

    • Real-time notifications
    • Direct messaging/chat
    • User status updates (online/offline)
    • STOMP protocol over SockJS
  • Notification System

    • Like notifications
    • Comment notifications
    • Follow notifications
    • New post alerts
    • Read/unread tracking

Admin Features

  • User management (delete, ban)
  • Post moderation (hide, delete)
  • Report management
  • Analytics dashboard
    • User count
    • Post count
    • Comment count
    • Report count

Content Moderation

  • Report system for users, posts, and comments
  • Priority levels
  • Report status tracking (solved/unsolved)
  • Admin review and resolution

Media Handling

  • Image upload and storage
  • Video file support
  • UUID-based file naming
  • Multiple format support (JPEG, PNG, GIF, MP4, WebM)

Performance & Caching

  • Redis Caching: In-memory caching for frequently accessed data
    • User profile caching for improved retrieval performance
    • Configurable cache expiration
    • Redis on localhost:6379 (default)
    • Spring Data Redis integration

Project Structure

backend/
├── src/
│   ├── main/
│   │   ├── java/com/blog/backend/
│   │   │   ├── config/                             # Application Configuration
│   │   │   │   ├── security/                       # Security & authentication
│   │   │   │   │   ├── SecurityConfig.java
│   │   │   │   │   ├── filters/                    # 3-layer authentication filters
│   │   │   │   │   ├── cors/
│   │   │   │   │   └── service/
│   │   │   │   ├── redis/                          # Redis cache configuration
│   │   │   │   ├── tomcat/                         # Tomcat & rate limiting
│   │   │   │   └── seed/
│   │   │   │
│   │   │   ├── controllers/                        # REST API endpoints (12 controllers)
│   │   │   ├── models/                             # JPA entities (13 entities)
│   │   │   │   └── base/
│   │   │   ├── services/                           # Business logic layer
│   │   │   │   ├── user/
│   │   │   │   ├── post/
│   │   │   │   ├── social/
│   │   │   │   └── media/
│   │   │   ├── repositories/                       # Data access layer (12 repositories)
│   │   │   ├── dto/                                # Data Transfer Objects
│   │   │   │   ├── user/
│   │   │   │   ├── post/
│   │   │   │   ├── comment/
│   │   │   │   ├── chat/
│   │   │   │   ├── report/
│   │   │   │   └── oauth2/
│   │   │   ├── websocket/                          # WebSocket handlers
│   │   │   ├── enums/                              # Enumerations
│   │   │   ├── exceptions/                         # Exception handling
│   │   │   ├── records/                            # Java records
│   │   │   └── Main.java
│   │   │
│   │   └── resources/
│   │       ├── application.properties
│   │       ├── db/migration/                       # 14 Flyway migrations
│   │       └── media/                              # User-uploaded files
│   │
│   └── test/                                       # Test sources
│
├── pom.xml
├── Dockerfile
├── docker-compose.yml
├── application-secret.properties
└── README.md

Getting Started

Prerequisites

  • Java 17 or higher
  • Maven 3.6+
  • PostgreSQL database
  • Environment variables or application.properties configured

Installation

  1. Clone and navigate to backend directory
cd backend
  1. Configure database

Create a PostgreSQL database:

CREATE DATABASE mydb;
CREATE USER amine WITH PASSWORD '1234';
GRANT ALL PRIVILEGES ON DATABASE mydb TO amine;
  1. Update application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=amine
spring.datasource.password=1234
  1. Build the project
mvn clean install
  1. Run the application
# Using Maven
mvn spring-boot:run

# Or using the run script
./run.sh

# Or run the JAR
java -jar target/backend-0.0.1-SNAPSHOT.jar

The API will be available at http://localhost:8080

Database Migrations

Flyway migrations run automatically on startup. Migration files are in:

src/main/resources/db/migration/

Current migrations:

  1. V1 - Users table
  2. V2 - Posts table
  3. V3 - Post interactions table
  4. V4 - Comments table
  5. V5 - Comment interactions table
  6. V6 - Categories and post categories tables
  7. V7 - Followers table
  8. V8 - Messages table
  9. V9 - Notifications table
  10. V10 - Saved posts table
  11. V11 - Reports table
  12. V12 - Add provider columns to users (OAuth2 support)
  13. V13 - Change avatar column to TEXT type
  14. V14 - Populate fake data (development seeding)

API Endpoints

Authentication

Register User

POST /api/users/register
Content-Type: application/json

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "password": "password123",
  "description": "Bio text"
}

Login

POST /api/users/login
Authorization: Basic base64(email:password)

Response: JWT token string

OAuth2 Login

Google OAuth2

GET /auth/google
# Redirects to Google login page
# Callback: GET /auth/google/callback?code={code}
# Redirects to: http://localhost:4200/login?token={jwt}

GitHub OAuth2

GET /auth/github
# Redirects to GitHub authorization page
# Callback: GET /auth/github/callback?code={code}
# Redirects to: http://localhost:4200/login?token={jwt}

Facebook OAuth2

GET /auth/facebook
# Redirects to Facebook login dialog
# Callback: GET /auth/facebook/callback?code={code}
# Redirects to: http://localhost:4200/login?token={jwt}

OAuth2 Flow:

  1. User clicks OAuth provider button in frontend
  2. Frontend redirects to /auth/{provider}
  3. Backend redirects to provider's authorization page
  4. User authorizes the application
  5. Provider redirects to /auth/{provider}/callback with authorization code
  6. Backend exchanges code for access token
  7. Backend fetches user info from provider
  8. Backend creates or retrieves user from database
  9. Backend generates JWT token
  10. Backend redirects to frontend with JWT token

User Management

Get Current User

POST /api/users/me
Authorization: Bearer <jwt_token>

Get User Profile

GET /api/users/profile/{id}
Authorization: Bearer <jwt_token>

Update User

PATCH /api/users/update
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "avatar": "filename.png",
  "description": "Updated bio"
}

Delete Account

DELETE /api/users/delete
Authorization: Bearer <jwt_token>

Posts

Create Post

POST /api/posts/create
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "title": "Post Title",
  "description": "Post content...",
  "banner": "image.png",
  "categories": [1, 2, 3]
}

Get Post by ID

GET /api/posts/{id}
Authorization: Bearer <jwt_token>

Get Posts (with filters)

GET /api/posts/?id=1&ownerId=2&searsh=keyword&category=Technology&savedPosts=true&offset=0
Authorization: Bearer <jwt_token>

Update Post

PATCH /api/posts/update
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "id": 1,
  "title": "Updated Title",
  "description": "Updated content",
  "banner": "new-image.png",
  "categories": [1, 2]
}

Delete Post

DELETE /api/posts/delete/{post_id}
Authorization: Bearer <jwt_token>

Toggle Like Post

POST /api/posts/interactions/toggle/{post_id}
Authorization: Bearer <jwt_token>

Toggle Save Post

POST /api/posts/saves/toggle/{post_id}
Authorization: Bearer <jwt_token>

Comments

Create Comment

POST /api/comments/create/{parentId}
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "content": "Comment text",
  "postId": 1
}

# For nested replies, parentId is the parent comment ID
# For top-level comments, parentId is the post ID

Get Comments

GET /api/comments/{postId}
Authorization: Bearer <jwt_token>

Delete Comment

DELETE /api/comments/delete/{id}
Authorization: Bearer <jwt_token>

Toggle Like Comment

POST /api/comments/interactions/toggle/{comment_id}
Authorization: Bearer <jwt_token>

Social Features

Toggle Follow User

POST /api/users/follow/toggle/{id}
Authorization: Bearer <jwt_token>

Get Followers

GET /api/users/followers/{id}
Authorization: Bearer <jwt_token>

Get Following

GET /api/users/followings/{id}
Authorization: Bearer <jwt_token>

Get Friends List

GET /api/users/friends
Authorization: Bearer <jwt_token>

Notifications

Get All Notifications

POST /api/notifications
Authorization: Bearer <jwt_token>

Mark Notification as Read

POST /api/notifications/{id}
Authorization: Bearer <jwt_token>

Mark All as Read

POST /api/notifications/
Authorization: Bearer <jwt_token>

Reports

Create Report

POST /api/reports/
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "reportedId": 1,
  "issue": "Spam",
  "description": "This is spam content",
  "priority": "HIGH",
  "postId": 1,        # Optional
  "commentId": null,  # Optional
  "userId": null      # Optional
}

Get All Reports (Admin)

POST /api/reports/all
Authorization: Bearer <jwt_token>

Delete Report (Admin)

DELETE /api/reports/{report_id}
Authorization: Bearer <jwt_token>

Toggle Report Status (Admin)

PATCH /api/reports/toggle/{report_id}
Authorization: Bearer <jwt_token>

Admin

Get Statistics

POST /api/admin/numbers
Authorization: Bearer <jwt_token>

Response:
{
  "userCount": 100,
  "postCount": 500,
  "commentCount": 1500,
  "reportCount": 10
}

Get All Users

POST /api/admin/users
Authorization: Bearer <jwt_token>

Get All Posts

POST /api/admin/posts
Authorization: Bearer <jwt_token>

Delete User

DELETE /api/admin/users/delete/{id}
Authorization: Bearer <jwt_token>

Hide/Unhide Post

POST /api/admin/posts/hide/{id}
Authorization: Bearer <jwt_token>

Delete Post

DELETE /api/admin/posts/delete/{id}
Authorization: Bearer <jwt_token>

Ban User

PATCH /api/users/ban/{id}
Authorization: Bearer <jwt_token>

Chat

Get Chat History

POST /api/chat/get/{id}
Authorization: Bearer <jwt_token>

Media

Get Media File

GET /api/media/{filename}

Security Architecture

Authentication Filter Chain

The security system uses 3 ordered filters:

1. PublicEndpointsFilter (Order 1)

  • Purpose: Handle public endpoints
  • Public Endpoints:
    • /api/users/login
    • /api/users/register
    • /api/media/*
  • Behavior: Sets guest authentication, clears security context

2. GuestAccessFilter (Order 2)

  • Purpose: Grant limited guest access
  • Behavior:
    • Allows GET requests without authentication
    • Allows access to /api/reports/
    • Returns 401 for unauthorized protected endpoints

3. JwtAuthenticationFilter (Order 3)

  • Purpose: Validate JWT tokens
  • Header: Authorization: Bearer <token>
  • Behavior:
    • Extracts and validates JWT
    • Sets authentication in SecurityContext
    • Returns appropriate error codes (401, 400, 500)

JWT Configuration

Token Details:

  • Secret: Configured in application (44+ bytes for HS256)
  • Expiration: 12 hours
  • Algorithm: HS256
  • Claims: User ID (subject), Role

Token Generation:

String token = Jwts.builder()
    .setSubject(String.valueOf(userId))
    .claim("role", userRole)
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis() + 12 * 60 * 60 * 1000))
    .signWith(SignatureAlgorithm.HS256, secret)
    .compact();

CORS Configuration

Allowed Origin: http://localhost:4200 (Angular frontend)

Allowed Methods:

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH
  • OPTIONS

Credentials: Allowed (for session cookies)

Password Security

  • Encoding: BCryptPasswordEncoder
  • Strength: Default BCrypt strength (10 rounds)
  • Validation: Plain password compared with encoded password during login

Database Schema

User Table

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    first_name VARCHAR(255) NOT NULL,
    last_name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role VARCHAR(50) DEFAULT 'ROLE_USER',
    is_banned BOOLEAN DEFAULT FALSE,
    is_online BOOLEAN DEFAULT FALSE,
    avatar TEXT,                      -- Changed to TEXT for long OAuth2 URLs
    description TEXT,
    provider VARCHAR(50),             -- OAuth2 provider (google, github, facebook)
    provider_id VARCHAR(255),         -- User ID from OAuth2 provider
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Post Table

CREATE TABLE posts (
    id BIGSERIAL PRIMARY KEY,
    title VARCHAR(500) NOT NULL,
    description TEXT NOT NULL,
    banner VARCHAR(255),
    is_hidden BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    user_id BIGINT REFERENCES users(id) ON DELETE CASCADE
);

Comment Table

CREATE TABLE comments (
    id BIGSERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
    post_id BIGINT REFERENCES posts(id) ON DELETE CASCADE,
    parent_id BIGINT REFERENCES comments(id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Interaction Table (Post Likes)

CREATE TABLE interactions (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
    post_id BIGINT REFERENCES posts(id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(user_id, post_id)
);

Other Tables

  • comment_interactions: Comment likes
  • categories: Post categories
  • post_categories: Many-to-many relationship
  • followers: Follow relationships
  • saved_posts: Bookmarked posts
  • notifications: User notifications
  • messages: Direct messages
  • reports: Content reports

Real-Time Communication

WebSocket Configuration

Endpoint: /ws

Protocol: STOMP over SockJS

Authentication: JWT token in connection query parameter

ws://localhost:8080/ws?token=<jwt_token>

Message Destinations

Client Subscribe

/user/{userId}/queue/notifications  - Receive notifications
/user/{userId}/queue/chat          - Receive messages
/topic/user-status                 - User online/offline status

Client Send

/app/chat  - Send chat message

WebSocket Controller

Send Chat Message

@MessageMapping("/chat")
public void sendMessage(@Payload MessageDTO message, Principal principal) {
    // Process and send message
    messagingTemplate.convertAndSendToUser(
        String.valueOf(receiverId),
        "/queue/chat",
        messageDTO
    );
}

Send Notification

public void sendNotification(long recipientId, FullNotification notification) {
    messagingTemplate.convertAndSendToUser(
        String.valueOf(recipientId),
        "/queue/notifications",
        notification
    );
}

Notification Types

public enum NotifType {
    LIKE,       // Post or comment liked
    COMMENT,    // New comment on post
    FOLLOW,     // New follower
    NEW_POST    // New post from followed user
}

Configuration

application.properties

# Application Name
spring.application.name=backend

# Database Configuration
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=amine
spring.datasource.password=1234
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false

# Flyway Configuration
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration

# Session Configuration
server.servlet.session.timeout=1m
server.servlet.session.cookie.max-age=1m
server.servlet.session.tracking-modes=cookie
server.servlet.session.cookie.same-site=lax
server.servlet.session.cookie.secure=false

# File Upload Configuration
spring.servlet.multipart.max-request-size=10MB

# Media Configuration
app.media.base-url=${MEDIA_BASE_URL:http://localhost:8080/api/media/}

# Redis Configuration
spring.redis.host=localhost
spring.redis.port=6379

# OAuth2 Secrets (imported from application-secret.properties)
spring.config.import=file:application-secret.properties

JWT Configuration

Set in SecurityConfig or environment:

private static final String SECRET = "this-is-a-very-strong-secret-key-12345678";
private static final long EXPIRATION_TIME = 12 * 60 * 60 * 1000; // 12 hours

Redis Configuration

Redis Cache Setup:

Configure Redis connection in application.properties:

spring.redis.host=localhost
spring.redis.port=6379

Cache Configuration (RedisConfig.java):

  • RedisCacheManager for Spring Cache abstraction
  • Jackson2JsonRedisSerializer for object serialization
  • Configurable cache expiration times
  • Used for user profile caching to reduce database queries

Starting Redis:

# Using Docker
docker run -d -p 6379:6379 redis:latest

# Or install locally
# macOS: brew install redis
# Ubuntu: sudo apt-get install redis-server

OAuth2 Configuration

Configure OAuth2 providers in application.properties or environment variables:

Google OAuth2

google.client.id=your-google-client-id
google.client.secret=your-google-client-secret

GitHub OAuth2

github.client.id=your-github-client-id
github.client.secret=your-github-client-secret

Facebook OAuth2

facebook.client.id=your-facebook-app-id
facebook.client.secret=your-facebook-app-secret

OAuth2 Provider Setup:

  1. Google Cloud Console

    • Create project at https://console.cloud.google.com
    • Enable Google+ API
    • Create OAuth 2.0 credentials
    • Add redirect URI: http://localhost:8080/auth/google/callback
    • Copy Client ID and Client Secret
  2. GitHub Developer Settings

  3. Facebook Developers

    • Create app at https://developers.facebook.com
    • Add Facebook Login product
    • Set Valid OAuth Redirect URI: http://localhost:8080/auth/facebook/callback
    • Copy App ID and App Secret

User Database Fields for OAuth2:

  • provider (VARCHAR): Provider name (google, github, facebook, or null for regular users)
  • provider_id (VARCHAR): User ID from OAuth provider
  • avatar (TEXT): Profile picture URL from provider (stored as TEXT to support long URLs)
  • password (VARCHAR): Empty string for OAuth users

Media Storage

Path: ./src/main/resources/media/

Naming: UUID-based (e.g., 87a8d7c9-3914-45d3-b98f-846cff64b323.png)

Upload Limit: 10MB maximum file size

Base URL: Configurable via app.media.base-url (default: http://localhost:8080/api/media/)

Supported Formats:

  • Images: JPEG, PNG, GIF
  • Videos: MP4, WebM

Testing

The backend uses a comprehensive testing stack with JUnit 5 for unit/integration tests and REST Assured 5.3.1 for API endpoint testing.

Testing Technologies

  • JUnit 5: Modern testing framework for Java

    • Unit tests for service layer
    • Integration tests for repositories
    • Test lifecycle management with @BeforeEach, @AfterEach
  • REST Assured 5.3.1: Fluent API for testing REST services

    • HTTP request/response testing
    • JSON/XML validation
    • Authentication testing
    • Status code assertions
  • Spring Boot Test: Testing utilities

    • @SpringBootTest for integration tests
    • MockMvc for controller testing
    • @DataJpaTest for repository testing

Running Tests

# Run all tests
mvn test

# Run specific test class
mvn test -Dtest=UserServiceTest

# Run tests with coverage report
mvn test jacoco:report

# Run only unit tests
mvn test -Dgroups=unit

# Run only integration tests
mvn test -Dgroups=integration

# Skip tests during build
mvn clean package -DskipTests

Example REST Assured Test

@Test
void testGetUserProfile() {
    given()
        .header("Authorization", "Bearer " + jwtToken)
        .pathParam("id", userId)
    .when()
        .get("/api/users/profile/{id}")
    .then()
        .statusCode(200)
        .body("firstName", equalTo("John"))
        .body("email", equalTo("john@example.com"));
}

Test Coverage

To generate test coverage reports:

mvn clean test jacoco:report

# View report at: target/site/jacoco/index.html

Deployment

Option 1: Docker Compose (Recommended)

The easiest way to run the entire backend stack including PostgreSQL:

# Navigate to backend directory
cd backend

# Start all services
docker-compose up

# Start in detached mode
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose down

What it does:

  • Builds the Spring Boot application using multi-stage Dockerfile
  • Starts PostgreSQL 18 database with health checks
  • Waits for database to be ready before starting backend
  • Exposes backend on port 8080
  • Exposes PostgreSQL on port 5432

docker-compose.yml:

version: '3.9'
services:
  db:
    image: postgres:18
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: amine
      POSTGRES_PASSWORD: 1234
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U amine -d mydb"]
      interval: 5s
      retries: 5

  backend:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/mydb
      SPRING_DATASOURCE_USERNAME: amine
      SPRING_DATASOURCE_PASSWORD: 1234

Dockerfile (Multi-stage build):

# Build stage
FROM maven:3.9.3-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY mvnw .
COPY .mvn .mvn
COPY src src
RUN ./mvnw clean package -DskipTests

# Run stage
FROM eclipse-temurin:17-jdk
WORKDIR /app
COPY --from=build /app/target/backend-0.0.1-SNAPSHOT.jar app.jar
COPY application-secret.properties application-secret.properties
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]

Option 2: Production Build (Manual)

# Build the application
mvn clean package -DskipTests

# Run in production
java -jar target/backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

Option 3: Docker Only (No Compose)

# Build the image
docker build -t blog-backend .

# Run PostgreSQL
docker run -d \
  --name postgres \
  -e POSTGRES_DB=mydb \
  -e POSTGRES_USER=amine \
  -e POSTGRES_PASSWORD=1234 \
  -p 5432:5432 \
  postgres:18

# Run backend (after DB is ready)
docker run -d \
  --name blog-backend \
  -p 8080:8080 \
  -e SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/mydb \
  -e SPRING_DATASOURCE_USERNAME=amine \
  -e SPRING_DATASOURCE_PASSWORD=1234 \
  blog-backend

Environment Variables for Production

For production deployments, override these via environment variables:

# Database
SPRING_DATASOURCE_URL=jdbc:postgresql://production-host:5432/mydb
SPRING_DATASOURCE_USERNAME=your_user
SPRING_DATASOURCE_PASSWORD=your_secure_password

# JWT
JWT_SECRET=your-very-strong-production-secret-key-minimum-44-bytes

# OAuth2 (if using)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
FACEBOOK_CLIENT_ID=your-facebook-app-id
FACEBOOK_CLIENT_SECRET=your-facebook-app-secret

Error Handling

Global Exception Handler

All exceptions are handled centrally:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(GlobalException.class)
    public ResponseEntity<String> handleGlobalException(GlobalException ex) {
        return ResponseEntity.status(ex.getStatus()).body(ex.getMessage());
    }
}

Common Error Codes

  • 400: Bad Request (validation errors)
  • 401: Unauthorized (invalid/missing token)
  • 403: Forbidden (insufficient permissions)
  • 404: Not Found (resource doesn't exist)
  • 500: Internal Server Error

Performance Considerations

  • Redis Caching: In-memory caching layer for user profiles and frequently accessed data
  • Database Indexing: Applied on frequently queried columns
  • Connection Pooling: HikariCP (Spring Boot default)
  • Lazy Loading: JPA relationships are lazily loaded
  • Pagination: Implemented via query parameters
  • Cache Eviction: Automatic cache invalidation on data updates

Security Best Practices

  1. Passwords: BCrypt encrypted, never stored in plain text
  2. JWT: Signed with strong secret, expiration enforced
  3. Sessions: Short timeout (1 minute), one per user
  4. CORS: Restricted to frontend origin only
  5. SQL Injection: Prevented via JPA/Hibernate
  6. XSS: Sanitize user input on frontend
  7. Rate Limiting: Implemented in TomcatConfig

Contributing

  1. Follow Java code conventions
  2. Write unit tests for new features
  3. Update API documentation
  4. Use Lombok annotations appropriately
  5. Follow existing patterns for services and controllers

Support

For issues and questions, please contact the development team.


Back | FazBrowse Home | New Git URL