Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

backend-patterns

/backend-patterns

Stosuje produkcyjne wzorce backendu: middleware, obsługa błędów, uwierzytelnianie, integracja z bazą danych i projektowanie API w Express, Fastify i NestJS.

Licencja
MIT
Ostatnia zmiana repozytorium
15.05.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 15.05.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Stosuje produkcyjne wzorce backendu: middleware, obsługa błędów, uwierzytelnianie, integracja z bazą danych i projektowanie API w Express, Fastify i NestJS.

Oryginalny opis (EN)

Applies production backend patterns: middleware, error handling, auth, database integration, and API design. Use when working with backend service files or when the user mentions Express, Fastify, NestJS, backend patterns, or service architecture.

Jak działa

  1. Critical rules (non-obvious)
  2. Express: production setup
  3. Repository pattern
  4. Service layer with error types
  5. JWT middleware
  6. Database connection with retry
  7. Graceful shutdown
  8. Common pitfalls
Sekcje z nagłówków SKILL.md, w oryginale · 152 linii, 615 słów
Podgląd SKILL.md
---
name: backend-patterns
type: reference
description: "Applies production backend patterns: middleware, error handling, auth, database integration, and API design. Use when working with backend service files or when the user mentions Express, Fastify, NestJS, backend patterns, or service architecture."
paths: ["**/*.ts", "**/*.js", "**/server.*", "**/app.*", "**/routes/**"]
effort: 3
allowed-tools: Read, Glob, Grep, Write, Edit, Bash
context: fork
agent: backend-developer
user-invocable: true
when_to_use: "When building Node.js backend services with Express, Fastify, or similar frameworks"
---

# Backend Patterns

## Critical rules (non-obvious)

- **Always handle async errors in Express**: unhandled promise rejections crash the process; use `express-async-errors` or wrap every async handler
- **Never trust `req.body` size**: set `limit` on body-parser; default 100kb is too large for some, too small for others
- **`process.env` access at import time**: if accessed before `dotenv.config()`, value is undefined; call config() first in entry file
- **Connection pool misconfiguration**: default pool size (10) will exhaust under load; set `pool.max` based on `(num_cores * 2) + effective_spindle_count`
- **`res.json()` after `res.send()`**: causes "Cannot set headers after they are sent" — always `return` after sending response

## Express: production setup

```typescript
import express from "express";
import "express-async-errors";  // patches async error handling globally
import helmet from "helmet";
import { rateLimit } from "express-rate-limit";

const app = express();

app.use(helmet());
app.use(express.json({ limit: "10kb" }));
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));

// Routes
app.use("/api/v1/users", userRouter);
app.use("/api/v1/products", productRouter);

// 404 handler — must come after all routes
app.use((req, res) => res.status(404).json({ error: "Not found" }));

// Global error handler — must have 4 params
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  const status = err instanceof AppError ? err.statusCode : 500;
  res.status(status).json({ error: err.message });
});
```

## Repository pattern

```typescript
interface IUserRepository {
  findById(id: string): Promise<User | null>;
  findByEmail(email: string): Promise<User | null>;
  save(user: User): Promise<User>;
  delete(id: string): Promise<void>;
}

class PgUserRepository implements IUserRepository {
  constructor(private readonly db: Pool) {}

  async findById(id: string) {
    const { rows } = await this.db.query(
      "SELECT * FROM users WHERE id = $1 AND deleted_at IS NULL", [id]
    );
    return rows[0] ?? null;
  }
}
```

## Service layer with error types

```typescript
class AppError extends Error {
  constructor(public message: string, public statusCode: number) { super(message); }
}
class NotFoundError extends AppError { constructor(msg: string) { super(msg, 404); } }
class ForbiddenError extends AppError { constructor(msg: string) { super(msg, 403); } }

class UserService {
  async getUser(id: string, requesterId: string): Promise<User> {
    const user = await this.repo.findById(id);
    if (!user) throw new NotFoundError(`User ${id} not found`);
    if (user.id !== requesterId && !isAdmin(requesterId)) throw new ForbiddenError("Access denied");
    return user;
  }
}
```

## JWT middleware

```typescript
import jwt from "jsonwebtoken";

export function authenticate(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) return res.status(401).json({ error: "No token" });
  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload;
    next();
  } catch {
    res.status(401).json({ error: "Invalid token" });
  }
}
```

## Database connection with retry

```typescript
import { Pool } from "pg";

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,              // pool size
  idleTimeoutMillis: 30_000,
  connectionTimeoutMillis: 2_000,
});

// Test connection on startup
async function connectWithRetry(retries = 5, delay = 2000) {
  for (let i = 0; i < retries; i++) {
    try {
      await pool.query("SELECT 1");
      console.log("DB connected");
      return;
    } catch (err) {
      if (i === retries - 1) throw err;
      await new Promise(r => setTimeout(r, delay * (i + 1)));  // exponential backoff
    }
  }
}
```

## Graceful shutdown

```typescript
const server = app.listen(PORT);

async function shutdown(signal: string) {
  console.log(`${signal} received. Shutting down gracefully.`);
  server.close(async () => {
    await pool.end();  // drain DB connections
    process.exit(0);
  });
  setTimeout(() => process.exit(1), 10_000);  // force exit after 10s
}

process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));
```

## Common pitfalls

| Pitfall | Fix |
|---|---|
| Async handler without try/catch | Use `express-async-errors` package |
| `await` inside `forEach` | Use `Promise.all(array.map(async...))` |
| Logging raw errors to client | Log internally; return sanitized message to client |
| Missing `return` after `res.json()` | Always `return res.json(...)` to stop execution |
| Secrets in `config.js` | Use `process.env` + validation on startup |

Wersje

RepozytoriumWynikLicencja
Ta strona · tranhieutt/software_development_department100MIT
tadokoro-ryusuke/cc-plugins100MIT
kensaurus/cursor-kenji100MIT
affaan-m/ECC95MIT
affaan-m/ECC95MIT
andersonlimahw/lemon-ai-hub95MIT

Migawka bazy z 28.10.2026 · wersja paczki c5a63098a20b (skrót SHA-256 całej paczki)

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100nodejs-backend-patterns
    Buduje produkcyjne usługi backendowe w Node.js z Express lub Fastify: wzorce middleware, obsługa błędów, uwierzytelnianie, integracja z bazą danych i dobre praktyki API.
  • 91nodejs-backend-patterns
    Buduje produkcyjne usługi backendowe w Node.js z Express lub Fastify: middleware, obsługa błędów, uwierzytelnianie, integracja z bazą danych i projektowanie API.
  • 100nodejs-backend-patterns
    Buduje usługi backendowe Node.js z Express lub Fastify: middleware, obsługa błędów, uwierzytelnianie, integracja z bazą i projektowanie API, dla serwerów, REST API, backendów GraphQL i mikroserwisów.
  • 91nodejs-backend-patterns
    Tworzy usługi backendowe w Node.js na Express lub Fastify, w tym serwery REST API, backendy GraphQL i mikrousługi, z wzorcami middleware, błędów i uwierzytelniania.
  • 100express
    Dostarcza wzorce backendu Express.js: routing, middleware, obsługa błędów, konfiguracja TypeScript i testy, przy budowaniu lub refaktoryzacji usługi Node.js.
  • 100senior-backend
    Wspiera rozwój backendu w Node.js, Express i Fastify: projektowanie REST API, optymalizacja PostgreSQL, bezpieczeństwo API i wzorce architektury backendowej.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.