Dezvoltarea Backend-urilor REST și Microserviciilor de Mare Viteză cu Dart Shelf, Routing și Middleware Asincron în Dart

HTTP (dart:io) Shelf 1.4+ / Dart 3.0+

Ghid enterprise pentru backend-uri Dart: arhitectura serverelor HTTP cu Shelf, pipeline de middleware (logging, CORS, autentificare JWT), rutare avansată cu shelf_router, serializare JSON și containerizare Docker distroless sub 25 MB.

Sintaxă
final handler = Pipeline().addMiddleware(logRequests()).addHandler(router.call);

În mod tradițional, Dart a fost privit exclusiv ca un limbaj pentru client și aplicații mobile Flutter. Cu toate acestea, în ultimii ani, adoptarea Dart pe server a crescut exponențial în arhitecturile enterprise. Motivul este strategic: partajarea integrală a codului de domeniu, a entităților de date și a validărilor de afaceri între aplicația client Flutter și backend, eliminând complet munca duplicată și discrepanțele dintre echipe.

Pentru dezvoltarea backend-urilor de înaltă performanță, ecosistemul oficial Dart pune la dispoziție Shelf: un framework HTTP minimalist, modular și compozabil, inspirat din Rack (Ruby) și Connect (Node.js), bazat pe un pipeline asincron de Middleware și Handler.

Arhitectura Pipeline în Dart Shelf
# Cerere HTTP Sosită de la Client
#              │
#              ▼
# ┌─────────────────────────────────────────────────────────┐
# │                   Pipeline Shelf                        │
# │  ├── Middleware 1: Logging & Corelație (X-Request-ID)   │
# │  ├── Middleware 2: Securitate CORS & Content-Type       │
# │  └── Middleware 3: Autentificare JWT / Bearer Token     │
# └────────────────────────────┬────────────────────────────┘
#                              │
#                              ▼
# ┌─────────────────────────────────────────────────────────┐
# │           shelf_router (Dispecer Rute REST)             │
# │  ├── GET  /api/v1/health   ──► Handler Sănătate         │
# │  ├── GET  /api/v1/users    ──► Controller Utilizatori   │
# │  └── POST /api/v1/orders   ──► Controller Comenzi       │
# └────────────────────────────┬────────────────────────────┘
#                              │
#                              ▼
#                Răspuns HTTP JSON Generat Rapid (<5ms)

Tabel Comparativ: Dart Shelf vs Node.js Express vs Go (Gin)

Criteriu Tehnic Dart Shelf (Compilat AOT) Node.js (Express) Go (Gin Framework)
Mod Compilare Ahead-Of-Time (Binar Nativ) Just-In-Time (V8 Engine) Ahead-Of-Time (Binar Nativ)
Timp de Pornire (Cold Start) Sub 25 milisecunde 300 – 800 ms Sub 15 milisecunde
Amprentă Memorie RAM (Idle) 15 – 30 MB RAM 70 – 130 MB RAM 10 – 25 MB RAM
Siguranță Tipuri Totală (Sound Null Safety + Dart 3) Opțională (doar prin TypeScript) Totală (Static tipizat)
Partajare Cod cu Frontend 100% (Identic cu Flutter) Doar cu React/Vue (JS/TS) Zero (Baze de cod separate)
server.dart – Microserviciu REST Complet de Producție
import 'dart:convert';
import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_router/shelf_router.dart';

// 1. Middleware de Autentificare prin Bearer Token
Middleware checkAuthToken() {
  return (Handler innerHandler) {
    return (Request request) async {
      // Endpoint-urile publice nu necesită autentificare:
      if (request.url.path == 'health' || request.url.path.startsWith('public')) {
        return innerHandler(request);
      }

      final authHeader = request.headers['Authorization'];
      if (authHeader == null || !authHeader.startsWith('Bearer ')) {
        return Response(HttpStatus.unauthorized,
            body: jsonEncode({'error': 'Token de autentificare lipsă'}),
            headers: {'content-type': 'application/json'});
      }

      final token = authHeader.substring(7);
      if (token != 'secret-api-token-123') {
        return Response(HttpStatus.forbidden,
            body: jsonEncode({'error': 'Token invalid sau expirat'}),
            headers: {'content-type': 'application/json'});
      }

      return innerHandler(request);
    };
  };
}

// 2. Definirea Rutelor cu shelf_router
Router createApiRouter() {
  final router = Router();

  // Health check pentru Kubernetes Liveness Probe:
  router.get('/health', (Request request) {
    return Response.ok(
      jsonEncode({'status': 'UP', 'engine': 'Dart-Shelf-AOT', 'version': '3.0'}),
      headers: {'content-type': 'application/json'},
    );
  });

  // Creare resursă asincronă cu validare:
  router.post('/api/v1/orders', (Request request) async {
    try {
      final payload = await request.readAsString();
      final data = jsonDecode(payload) as Map;

      final amount = data['amount'] as num?;
      if (amount == null || amount <= 0) {
        return Response.badRequest(
          body: jsonEncode({'error': 'Valoarea comenzii trebuie să fie pozitivă'}),
          headers: {'content-type': 'application/json'},
        );
      }

      final responseData = {
        'orderId': 'ORD-${DateTime.now().millisecondsSinceEpoch}',
        'amount': amount,
        'status': 'CONFIRMED',
      };

      return Response(HttpStatus.created,
          body: jsonEncode(responseData),
          headers: {'content-type': 'application/json'});
    } catch (e) {
      return Response.internalServerError(
        body: jsonEncode({'error': 'Eroare internă de procesare JSON'}),
        headers: {'content-type': 'application/json'},
      );
    }
  });

  return router;
}

Future main() async {
  final port = int.parse(Platform.environment['PORT'] ?? '8080');

  // Pipeline complet cu Middleware compus:
  final handler = const Pipeline()
      .addMiddleware(logRequests())
      .addMiddleware(checkAuthToken())
      .addHandler(createApiRouter().call);

  final server = await shelf_io.serve(handler, InternetAddress.anyIPv4, port);
  print('Server Dart Shelf activ pe portul http://${server.address.host}:${server.port}');
}
Dockerfile Multi-Stage AOT Nativ (Imagine Distroless sub 25 MB)
# Etapa 1: Compilare binar nativ AOT cu SDK-ul oficial Dart
FROM dart:stable AS build
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get
COPY . .
RUN dart pub get --offline
RUN dart compile exe bin/server.dart -o bin/server

# Etapa 2: Imagine de rulare Distroless ultra-minimală și securizată
FROM gcr.io/distroless/base-debian12
COPY --from=build /app/bin/server /app/bin/server

EXPOSE 8080
USER nonroot:nonroot
ENTRYPOINT ["/app/bin/server"]