Ensiklopedia VibeKoding: An Introduction to Backend Project Architecture.Ensiklopedia VibeKoding: An Introduction to Backend Project Architecture.
From simple scripts to large distributed systems, how do you choose the right architecture for backend projects of different scales and languages? It's like asking: from a home workshop to a large factory, how do you design different production lines based on output and processes? Good backend architecture should evolve with business growth while fully leveraging language characteristics.From simple scripts to large distributed systems, how do you choose the right architecture for backend projects of different scales and languages? It's like asking: from a home workshop to a large factory, how do you design different production lines based on output and processes? Good backend architecture should evolve with business growth while fully leveraging language characteristics.
------
Backend project architecture should match business scale and user volume:Backend project architecture should match business scale and user volume:
| Level | Users | Concurrency | Typical Scenario | Key Focus |
|---|---|---|---|---|
| Entry | < 1k | < 100 | Personal projects, MVP, internal tools | Rapid development, simple deployment |
| Intermediate | 1k-100k | 100-10k | Enterprise systems, SaaS, mid-size platforms | Layered architecture, coding standards |
| Enterprise | > 100k | > 10k | Large platforms, internet applications | Microservices, high availability, performance optimization |
Different programming languages have different design philosophies and ecosystems โ architecture design should align with language characteristics:Different programming languages have different design philosophies and ecosystems โ architecture design should align with language characteristics:
| Language | Design Philosophy | Recommended Architecture | Representative Frameworks |
|---|---|---|---|
| Node.js | Event-driven, non-blocking I/O | Layered architecture + async flows | Express, NestJS, Fastify |
| Python | Simple and elegant, rapid development | MTV/MVC, layered architecture | Django, Flask, FastAPI |
| Go | Simple and efficient, native concurrency | Clean layering, microservices | Gin, Echo, Fiber |
| Java | Enterprise-grade, strong typing | Strict layering, domain-driven | Spring Boot, Spring Cloud |
1. Don't over-engineer: Small projects use simple architectures; large projects need complex architectures 2. Follow language characteristics: Don't try to write Java-style code in Python 3. Progressive evolution: Start simple, optimize gradually as the business grows 4. Team familiarity: Choose architecture styles your team is familiar with to reduce learning costs1. Don't over-engineer: Small projects use simple architectures; large projects need complex architectures 2. Follow language characteristics: Don't try to write Java-style code in Python 3. Progressive evolution: Start simple, optimize gradually as the business grows 4. Team familiarity: Choose architecture styles your team is familiar with to reduce learning costs
------
Characteristics: Single file or simple split, quick to launchCharacteristics: Single file or simple split, quick to launch
CODE my-node-api/ โโโ src/ โ โโโ app.js # Application entry point โ โโโ routes.js # Route definitions โ โโโ db.js # Database connection โ โโโ utils.js # Utility functions โโโ .env # Environment variables โโโ package.json โโโ README.md
Code Example:Code Example:
javascript // src/app.js const express = require('express'); const app = express(); app.use(express.json()); // Routes written directly in the entry point (suitable when there are very few endpoints) app.get('/users', async (req, res) => { const users = await db.query('SELECT * FROM users'); res.json(users); }); app.post('/users', async (req, res) => { const { name, email } = req.body; const result = await db.query( 'INSERT INTO users (name, email) VALUES (?, ?)', [name, email] ); res.status(201).json({ id: result.insertId }); }); app.listen(3000, () => { console.log('Server running on port 3000'); });
Reference Open Source Projects:Reference Open Source Projects:
Characteristics: Leverage Python's simplicity for fast feature implementationCharacteristics: Leverage Python's simplicity for fast feature implementation
CODE my-python-api/ โโโ app.py # Main application โโโ models.py # Data models โโโ config.py # Configuration โโโ requirements.txt โโโ README.md
Code Example (Flask):Code Example (Flask):
python # app.py from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db' db = SQLAlchemy(app) # Model definitions class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) # Routes @app.route('/users', methods=['GET']) def get_users(): users = User.query.all() return jsonify([{'id': u.id, 'name': u.name, 'email': u.email} for u in users]) @app.route('/users', methods=['POST']) def create_user(): data = request.json user = User(name=data['name'], email=data['email']) db.session.add(user) db.session.commit() return jsonify({'id': user.id}), 201 if __name__ == '__main__': app.run(debug=True)
Reference Open Source Projects:Reference Open Source Projects:
Characteristics: Leverage Go's standard library with minimal dependenciesCharacteristics: Leverage Go's standard library with minimal dependencies
CODE my-go-api/ โโโ main.go # Entry point โโโ handlers.go # Handlers โโโ models.go # Models โโโ db.go # Database โโโ go.mod โโโ README.md
Code Example:Code Example:
go // main.go package main import ( "database/sql" "encoding/json" "log" "net/http" _ "github.com/mattn/go-sqlite3" ) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } var db *sql.DB func main() { var err error db, err = sql.Open("sqlite3", "./app.db") if err != nil { log.Fatal(err) } http.HandleFunc("/users", usersHandler) log.Println("Server starting on :8080") log.Fatal(http.ListenAndServe(":8080", nil)) } func usersHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: getUsers(w, r) case http.MethodPost: createUser(w, r) } } func getUsers(w http.ResponseWriter, r *http.Request) { rows, _ := db.Query("SELECT id, name, email FROM users") defer rows.Close() var users []User for rows.Next() { var u User rows.Scan(&u.ID, &u.Name, &u.Email) users = append(users, u) } json.NewEncoder(w).Encode(users) }
Reference Open Source Projects:Reference Open Source Projects:
Characteristics: Leverage Spring Boot's auto-configuration for quick startupCharacteristics: Leverage Spring Boot's auto-configuration for quick startup
CODE my-spring-app/ โโโ src/main/java/com/example/ โ โโโ controller/ โ โ โโโ UserController.java โ โโโ model/ โ โ โโโ User.java โ โโโ repository/ โ โ โโโ UserRepository.java โ โโโ Application.java โโโ src/main/resources/ โ โโโ application.yml โโโ pom.xml โโโ README.md
Code Example:Code Example:
java // Application.java @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } // User.java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // getters and setters } // UserRepository.java public interface UserRepository extends JpaRepository<User, Long> { } // UserController.java @RestController @RequestMapping("/users") public class UserController { @Autowired private UserRepository userRepository; @GetMapping public List<User> getAllUsers() { return userRepository.findAll(); } @PostMapping public User createUser(@RequestBody User user) { return userRepository.save(user); } }
Reference Open Source Projects:Reference Open Source Projects:
------
Intermediate projects are recommended to adopt a four-layer architecture (Controller-Service-Repository-Model):Intermediate projects are recommended to adopt a four-layer architecture (Controller-Service-Repository-Model):
CODE project/ โโโ src/ โ โโโ controllers/ # Controller layer: handles HTTP requests โ โโโ services/ # Service layer: business logic โ โโโ repositories/ # Repository layer: data access โ โโโ models/ # Model layer: data structures โ โโโ middlewares/ # Middleware โ โโโ utils/ # Utility functions โ โโโ config/ # Configuration โ โโโ routes/ # Route definitions โโโ tests/ โโโ docs/ โโโ scripts/
Reference Open Source Projects:Reference Open Source Projects:
CODE node-enterprise/ โโโ src/ โ โโโ modules/ # Organized by feature modules โ โ โโโ users/ โ โ โ โโโ users.controller.ts โ โ โ โโโ users.service.ts โ โ โ โโโ users.repository.ts โ โ โ โโโ users.module.ts โ โ โ โโโ dto/ โ โ โโโ orders/ โ โ โโโ products/ โ โโโ common/ # Shared modules โ โ โโโ filters/ # Exception filters โ โ โโโ guards/ # Guards โ โ โโโ interceptors/ # Interceptors โ โ โโโ pipes/ # Pipes โ โโโ config/ โ โโโ main.ts
NestJS Code Example:NestJS Code Example:
typescript // users/users.controller.ts @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() findAll(@Query() query: QueryUserDto) { return this.usersService.findAll(query); } @Post() create(@Body() createUserDto: CreateUserDto) { return this.usersService.create(createUserDto); } } // users/users.service.ts @Injectable() export class UsersService { constructor( @InjectRepository(User) private usersRepository: Repository<User>, ) {} async findAll(query: QueryUserDto) { const [data, total] = await this.usersRepository.findAndCount({ skip: (query.page - 1) * query.limit, take: query.limit, }); return { data, total }; } async create(createUserDto: CreateUserDto) { const user = this.usersRepository.create(createUserDto); return this.usersRepository.save(user); } }
Reference Open Source Projects:Reference Open Source Projects:
CODE django-enterprise/ โโโ apps/ โ โโโ users/ # Users app โ โ โโโ models.py โ โ โโโ views.py # API views โ โ โโโ serializers.py # Serializers โ โ โโโ permissions.py # Permissions โ โ โโโ urls.py โ โ โโโ tests/ โ โโโ orders/ โ โโโ products/ โโโ config/ # Project configuration โ โโโ settings/ โ โ โโโ base.py โ โ โโโ development.py โ โ โโโ production.py โ โโโ urls.py โ โโโ wsgi.py โโโ utils/ # Shared utilities โโโ templates/ โโโ static/ โโโ manage.py
Django REST Framework Code Example:Django REST Framework Code Example:
python # users/models.py from django.contrib.auth.models import AbstractUser class User(AbstractUser): phone = models.CharField(max_length=20, blank=True) avatar = models.URLField(blank=True) # users/serializers.py from rest_framework import serializers class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'username', 'email', 'phone', 'avatar'] # users/views.py from rest_framework import viewsets, permissions from rest_framework.decorators import action class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [permissions.IsAuthenticated] @action(detail=False, methods=['get']) def me(self, request): serializer = self.get_serializer(request.user) return Response(serializer.data) # users/urls.py from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'users', UserViewSet) urlpatterns = router.urls
Reference Open Source Projects:Reference Open Source Projects:
CODE go-enterprise/ โโโ cmd/ โ โโโ api/ # Application entry point โ โโโ main.go โโโ internal/ # Private code โ โโโ domain/ # Domain layer (entities, interfaces) โ โ โโโ user.go โ โ โโโ repository.go โ โโโ usecase/ # Use case layer (business logic) โ โ โโโ user_usecase.go โ โโโ delivery/ # Delivery layer (HTTP/gRPC) โ โ โโโ http/ โ โ โโโ user_handler.go โ โโโ repository/ # Repository layer (data access) โ โ โโโ user_repository.go โ โโโ config/ โโโ pkg/ # Public libraries โโโ migrations/ โโโ go.mod
Clean Architecture Code Example:Clean Architecture Code Example:
go // domain/user.go type User struct { ID int64 `json:"id"` Username string `json:"username"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // domain/repository.go type UserRepository interface { GetByID(ctx context.Context, id int64) (*User, error) GetByEmail(ctx context.Context, email string) (*User, error) Create(ctx context.Context, user *User) error Update(ctx context.Context, user *User) error } // usecase/user_usecase.go type UserUsecase struct { userRepo UserRepository } func (u *UserUsecase) GetByID(ctx context.Context, id int64) (*User, error) { return u.userRepo.GetByID(ctx, id) } func (u *UserUsecase) Create(ctx context.Context, user *User) error { // Business logic: check if email already exists existing, _ := u.userRepo.GetByEmail(ctx, user.Email) if existing != nil { return errors.New("email already exists") } return u.userRepo.Create(ctx, user) } // delivery/http/user_handler.go type UserHandler struct { UserUsecase *usecase.UserUsecase } func (h *UserHandler) GetUser(c *gin.Context) { id, _ := strconv.ParseInt(c.Param("id"), 10, 64) user, err := h.UserUsecase.GetByID(c.Request.Context(), id) if err != nil { c.JSON(404, gin.H{"error": "user not found"}) return } c.JSON(200, user) }
Reference Open Source Projects:Reference Open Source Projects:
CODE spring-enterprise/ โโโ src/main/java/com/example/ โ โโโ application/ # Application layer โ โ โโโ controller/ # Controllers โ โ โโโ dto/ # Data transfer objects โ โ โโโ assembler/ # Assemblers โ โโโ domain/ # Domain layer โ โ โโโ entity/ # Entities โ โ โโโ valueobject/ # Value objects โ โ โโโ repository/ # Repository interfaces โ โ โโโ service/ # Domain services โ โโโ infrastructure/ # Infrastructure layer โ โ โโโ repository/ # Repository implementations โ โ โโโ config/ # Configuration โ โ โโโ common/ # Utility classes โ โโโ Application.java โโโ src/main/resources/ โ โโโ application.yml โ โโโ mapper/ โโโ src/test/
Domain-Driven Design (DDD) Code Example:Domain-Driven Design (DDD) Code Example:
java // domain/entity/User.java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String username; @Column(nullable = false, unique = true) private String email; @Embedded private UserStatus status; // Domain methods public void deactivate() { this.status = UserStatus.INACTIVE; } public boolean isActive() { return this.status == UserStatus.ACTIVE; } } // domain/repository/UserRepository.java public interface UserRepository { Optional<User> findById(Long id); Optional<User> findByEmail(String email); User save(User user); void delete(User user); } // application/controller/UserController.java @RestController @RequestMapping("/api/v1/users") @RequiredArgsConstructor public class UserController { private final UserService userService; private final UserAssembler userAssembler; @GetMapping("/{id}") public ResponseEntity<UserDTO> getUser(@PathVariable Long id) { User user = userService.findById(id); return ResponseEntity.ok(userAssembler.toDTO(user)); } @PostMapping public ResponseEntity<UserDTO> createUser(@RequestBody @Valid CreateUserRequest request) { User user = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED) .body(userAssembler.toDTO(user)); } } // infrastructure/repository/UserRepositoryImpl.java @Repository @RequiredArgsConstructor public class UserRepositoryImpl implements UserRepository { private final UserJpaRepository jpaRepository; @Override public Optional<User> findById(Long id) { return jpaRepository.findById(id); } @Override public User save(User user) { return jpaRepository.save(user); } }
------
When a monolithic application can no longer meet requirements, consider a microservices architecture:When a monolithic application can no longer meet requirements, consider a microservices architecture:
CODE microservices-platform/ โโโ api-gateway/ # API Gateway โ โโโ src/ โ โโโ Dockerfile โโโ services/ # Business services โ โโโ user-service/ # User service โ โโโ order-service/ # Order service โ โโโ product-service/ # Product service โ โโโ payment-service/ # Payment service โโโ shared/ # Shared libraries โ โโโ proto/ # Protocol Buffers โ โโโ common-lib/ โ โโโ event-contracts/ โโโ infrastructure/ # Infrastructure โ โโโ docker-compose.yml โ โโโ kubernetes/ โ โโโ terraform/ โโโ docs/
| Language | Microservices Framework | Service Discovery | Config Center | Distributed Tracing |
|---|---|---|---|---|
| Node.js | NestJS + gRPC | Consul | etcd | Jaeger |
| Python | FastAPI + Nameko | Eureka | Consul | Zipkin |
| Go | Go-kit + gRPC | etcd | etcd | OpenTelemetry |
| Java | Spring Cloud | Nacos | Nacos | SkyWalking |
Monorepo (Single Repository):Monorepo (Single Repository):
CODE monorepo/ โโโ services/ โ โโโ user-service/ # Independent service โ โ โโโ src/ โ โ โโโ package.json โ โ โโโ Dockerfile โ โโโ order-service/ โ โโโ product-service/ โโโ shared/ โ โโโ types/ # Shared types โ โโโ utils/ # Shared utilities โ โโโ proto/ # Shared protocols โโโ packages/ โ โโโ eslint-config/ # Shared ESLint config โ โโโ ts-config/ # Shared TS config โโโ docker-compose.yml โโโ package.json # Root package.json
Advantages:Advantages:
Disadvantages:Disadvantages:
Polyrepo (Multiple Repositories):Polyrepo (Multiple Repositories):
Each service has its own repository:Each service has its own repository:
github.com/company/user-servicegithub.com/company/user-servicegithub.com/company/order-servicegithub.com/company/order-servicegithub.com/company/shared-libgithub.com/company/shared-libAdvantages:Advantages:
Disadvantages:Disadvantages:
Database Selection Strategy:Database Selection Strategy:
| Data Type | Recommended Database | Use Case |
|---|---|---|
| Relational data | PostgreSQL | Users, orders, products |
| Cache | Redis | Sessions, hot data |
| Search | Elasticsearch | Product search, logs |
| Time-series data | InfluxDB/TimescaleDB | Monitoring, metrics |
| Document data | MongoDB | Logs, configuration |
Data Access Layer Design:Data Access Layer Design:
CODE data-layer/ โโโ primary-db/ # Primary database โ โโโ master/ # Write database โ โโโ slaves/ # Read replicas โโโ cache-layer/ # Cache layer โ โโโ redis-cluster/ โ โโโ local-cache/ โโโ search-engine/ # Search engine โ โโโ elasticsearch/ โโโ message-queue/ # Message queue โโโ kafka/ โโโ rabbitmq/
------
Express.js Official Project Structure:Express.js Official Project Structure:
CODE express-project/ โโโ bin/ # Startup scripts โโโ public/ # Static assets โโโ routes/ # Routes โโโ views/ # Views โโโ app.js # Application configuration โโโ package.json
NestJS Official Recommendation:NestJS Official Recommendation:
CODE nest-project/ โโโ src/ โ โโโ modules/ # Feature modules โ โโโ common/ # Shared modules โ โโโ config/ โ โโโ main.ts โโโ test/ โโโ nest-cli.json
Django Official Project Structure:Django Official Project Structure:
CODE django-project/ โโโ project_name/ # Project configuration โโโ apps/ # Apps directory โโโ templates/ โโโ static/ โโโ media/ โโโ manage.py
FastAPI Project Structure:FastAPI Project Structure:
CODE fastapi-project/ โโโ app/ โ โโโ api/ โ โ โโโ deps.py # Dependencies โ โ โโโ v1/ โ โ โโโ endpoints/ โ โโโ core/ # Core configuration โ โโโ db/ # Database โ โโโ models/ # Models โ โโโ schemas/ # Pydantic models โ โโโ main.py โโโ tests/ โโโ alembic/ # Migrations
Standard Project Layout:Standard Project Layout:
CODE go-project/ โโโ cmd/ # Application entry points โ โโโ app/ โ โโโ main.go โโโ internal/ # Private code โโโ pkg/ # Public libraries โโโ api/ # API definitions โโโ web/ # Static assets โโโ configs/ # Configuration โโโ scripts/ # Scripts โโโ go.mod
Reference:Reference:
Spring Boot Official Structure:Spring Boot Official Structure:
CODE spring-boot-project/ โโโ src/main/java/com/example/ โ โโโ controller/ โ โโโ service/ โ โโโ repository/ โ โโโ entity/ โ โโโ dto/ โ โโโ config/ โ โโโ Application.java โโโ src/main/resources/ โ โโโ static/ โ โโโ templates/ โ โโโ application.yml โโโ src/test/
Alibaba Java Development Manual:Alibaba Java Development Manual:
------
CODE Phase 1: Monolithic Application (Entry Level) โ User growth, team expansion Phase 2: Layered Architecture (Intermediate Level) โ Business complexity, multi-team collaboration Phase 3: Modular/Microservices (Enterprise Level) โ High concurrency, high availability requirements Phase 4: Cloud-Native Architecture (Platform Level)
| Signal | Current Level | Recommended Upgrade |
|---|---|---|
| Code files > 50 | Entry | Intermediate |
| Build time > 5 minutes | Intermediate | Modular |
| Team > 10 people | Intermediate | Microservices |
| DAU > 100k | Intermediate | Enterprise |
| Multi-language tech stack | Monolith | Microservices |
------
Architecture serves the business, not architecture for architecture's sake. Choose by user count: - < 1k: Simple scripts, quick to launch - 1kโ100k: Layered architecture, coding standards - > 100k: Microservices, high-availability design Choose by language: - Node.js: Leverage async characteristics, suitable for I/O-intensive workloads - Python: Rapid development, suitable for data processing and AI - Go: High performance, suitable for cloud-native and microservices - Java: Enterprise-grade, suitable for large complex systems Universal principles: 1. Progressive evolution: Start simple, grow with the business 2. Convention over configuration: Unified standards reduce communication costs 3. Automated testing: Ensure safe refactoring 4. Documentation first: Record architectural decisions The ultimate goal: Make your code run as efficiently as a factory floor, regardless of scale.Architecture serves the business, not architecture for architecture's sake. Choose by user count: - < 1k: Simple scripts, quick to launch - 1kโ100k: Layered architecture, coding standards - > 100k: Microservices, high-availability design Choose by language: - Node.js: Leverage async characteristics, suitable for I/O-intensive workloads - Python: Rapid development, suitable for data processing and AI - Go: High performance, suitable for cloud-native and microservices - Java: Enterprise-grade, suitable for large complex systems Universal principles: 1. Progressive evolution: Start simple, grow with the business 2. Convention over configuration: Unified standards reduce communication costs 3. Automated testing: Ensure safe refactoring 4. Documentation first: Record architectural decisions The ultimate goal: Make your code run as efficiently as a factory floor, regardless of scale.
------