AI Reading
Quick summary of this article
This guide walks through building a full-stack blog application using Angular 20 for the frontend and Spring Boot for the backend. The project is split into three main parts: a Spring Boot REST API, a public Angular frontend for readers, and a separate Angular admin panel for content management. The architecture uses a decoupled design, with JWT-based authentication securing the admin operations.
- The project structure includes a Spring Boot backend handling users, posts, and categories, plus two separate Angular applications within a single workspace: one for the public blog UI and one for the admin panel.
- Setting up the backend requires Java 17+ and Spring Initializr with dependencies including Spring Web, Spring Security, Spring Data JPA, and a MySQL or H2 driver, with a recommended package structure separating controllers, services, entities, repositories, and security.
- Angular integration involves configuring HTTP client providers and services, with a BlogService example showing how to fetch posts from the backend API at
http://localhost:8080/api. - Authentication uses JWT tokens, implemented through an AuthService for login, an AdminGuard to protect routes based on user role, and an HTTP interceptor that automatically attaches the token to outgoing requests.
- The admin panel includes pages for dashboard stats, post listing/editing, and login, while the frontend provides home and post-detail pages; both apps run separately with the frontend on port 4200 and admin on port 4300.
π οΈ Building a Full-Stack Blog App with Angular 20 (Admin & Frontend) + Spring Boot Backend
Creating a modern, scalable, and efficient blog application involves a decoupled architecture where the frontend and backend are cleanly separated. In this comprehensive guide, we’ll walk through the entire process of building a full-stack blog using:
- β Angular 20 (Two separate apps: Admin Panel & Frontend Blog UI)
- β Spring Boot REST API (Java-based backend)
This article assumes you have basic familiarity with Angular and Spring Boot.
π¦ Project Overview
We will create:
- Backend (Spring Boot): Exposes a REST API for users, posts, categories.
- Frontend UI (Angular 20): For readers to browse blog posts.
- Admin Panel (Angular 20): For administrators to manage blog content.
Folder structure:
blog-project/
βββ blog-backend/ # Spring Boot backend (Java)
βββ blog-frontend/ # Angular workspace with multiple apps
β βββ admin-panel/ # Admin UI Angular app
β β βββ src/app/
β β βββ pages/
β β β βββ dashboard/
β β β βββ post-list/
β β β βββ post-editor/
β β β βββ login/
β β βββ services/
β β βββ guards/
β β βββ interceptors/
β β βββ models/
β β βββ app.routes.ts
β β βββ app.config.ts
β βββ frontend/ # Public Blog UI Angular app
β βββ src/app/
β βββ pages/
β β βββ home/
β β βββ post-detail/
β β βββ login/ (optional)
β βββ services/
β βββ guards/
β βββ models/
β βββ app.routes.ts
β βββ app.config.ts
π§ Step 1: Set Up Angular 20 Workspace
π¦ Prerequisites:
- Node.js 20+
- Angular CLI 20+
- Java 17+ or 21
π¨ Install Angular CLI
npm install -g @angular/cli@20
π© Create Angular Workspace (Without Initial App)
ng new blog-project --create-application=false
cd blog-project
π© Generate Admin and Frontend Apps
ng generate application admin-panel --standalone
ng generate application frontend --standalone
β
This creates two apps inside projects/
π οΈ Step 2: Angular Project Structure
Each app (admin-panel and frontend) will have its own folder with the structure shown above.
π Step 3: Set Up Spring Boot Backend
π¨ Use Spring Initializr:
- Dependencies:
- Spring Web
- Spring Security
- Spring Data JPA
- MySQL Driver (or H2)
π Recommended Package Structure
com.example.blog/
βββ controller/
βββ service/
βββ entity/
βββ repository/
βββ security/
βββ dto/
β Core Entities:
- User
- Post
- Category
Include authentication using JWT.
π§© Step 4: Integrate Frontend with Backend
π Install Zone.js (Angular Requirement)
npm install zone.js
Add at the top of main.ts:
import 'zone.js';
βοΈ Configure app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideRouter(routes)
]
};
π Setup API Services
@Injectable({ providedIn: 'root' })
export class BlogService {
private baseUrl = 'http://localhost:8080/api';
constructor(private http: HttpClient) {}
getAllPosts(): Observable<Post[]> {
return this.http.get<Post[]>(`${this.baseUrl}/posts`);
}
}
π Step 5: Authentication
π€ AuthService
@Injectable({ providedIn: 'root' })
export class AuthService {
login(email: string, password: string): Observable<{ token: string }> {
return this.http.post<{ token: string }>(`${this.baseUrl}/auth/login`, { email, password });
}
getUserFromToken(): User | null {
const token = localStorage.getItem('token');
if (!token) return null;
const payload = JSON.parse(atob(token.split('.')[1]));
return { id: payload.sub, email: payload.email, role: payload.role };
}
}
π‘οΈ Auth Guard
export const AdminGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const user = authService.getCurrentUser();
return user?.role === 'ADMIN';
};
π Add Auth Interceptor
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const token = localStorage.getItem('token');
return token ? next(req.clone({ setHeaders: { Authorization: `Bearer ${token}` } })) : next(req);
};
Add to app.config.ts:
provideHttpClient(withInterceptors([authInterceptor]))
πΌοΈ Step 6: UI Pages
π Admin Panel
dashboard: Show stats, recent postspost-list: List all posts, edit/deletepost-editor: Create or edit a postlogin: Form to authenticate admin
π° Frontend
home: List blog postspost-detail: View full post by sluglogin: (Optional if you want user login for comments)
π Step 7: Running the Apps
1. Start Backend
cd blog-backend
./mvnw spring-boot:run
2. Start Admin App
cd blog-project
ng serve --project=admin-panel --port=4300
3. Start Frontend App
ng serve --project=frontend
π Access
- Frontend:
http://localhost:4200 - Admin:
http://localhost:4300
