dartapi_core 0.6.0 copy "dartapi_core: ^0.6.0" to clipboard
dartapi_core: ^0.6.0 copied to clipboard

Core utilities for building typed, structured REST APIs in Dart, including routing, validation, and middleware support.

0.6.0 #

Session-wide token revocation — revokeAllForUser.

Until now the TokenStore could only revoke one token (jti) at a time, so the documented response to refresh-token reuse ("revoke the whole session") was not actually expressible with the framework's own APIs.

New features #

  • JwtService.revokeAllForUser(sub) — invalidates every outstanding access and refresh token for a subject. Tokens issued at or before the revocation moment are rejected by verifyAccessToken/verifyRefreshToken; a fresh login afterwards works normally. The revocation entry expires on its own once the longest-lived token would have expired anyway.
  • TokenStore.revokeSubject(sub, cutoffEpochSeconds:, ttl:) and TokenStore.subjectRevocationCutoff(sub) — the underlying primitives, with in-process default implementations on the base class. Like revokeIfActive, distributed backends (Redis, SQL) should override them with a shared store.
  • Session-revoked refresh tokens are rejected without firing onRefreshTokenReuse — a dead session is not a theft signal.

Notes #

  • The intended wiring, now actually possible:
    onRefreshTokenReuse: (payload) async {
      final sub = payload['sub'];
      if (sub is String) await jwtService.revokeAllForUser(sub);
    }
    
  • Reminder: InMemoryTokenStore (including its new subject entries) is per-process. Behind --isolates=N or multiple instances, use a shared TokenStore backend — a Redis adapter is on the roadmap.

0.5.0 #

OpenAPI overhaul — the spec now documents what the framework actually does, and the docs UI can't break under you.

Breaking changes #

  • DocsController now takes a lazy routesProvider: () => routes instead of apiRoutes: routes. If you only use app.enableDocs(), nothing changes — but enableDocs may now be called before or after addControllers (routes are collected on first request, removing the silent "controllers registered after enableDocs are missing from the docs" footgun).
  • The spec version is now 3.0.3 (was 3.0.0).
  • The three docs routes (/openapi.json, /docs, /redoc) no longer appear in the generated spec.

New features #

  • ApiRoute.requestFields: FieldSet — pass the same FieldSet that validates the request; the request body schema is derived from it. One declaration, zero drift between validation and documentation.
  • Automatic error responses. Routes with a body parser document 422 Validation Error and 400 Bad Request (schemas match the real error envelopes: {"errors":[{"field","message"}]} and {"error","message"}); routes with security document 401 Unauthorized. ValidationError/Error component schemas are added automatically.
  • ApiRoute.responses: {404: ResponseSpec('Not found', schema: ...)} — document any additional responses; explicit entries override the automatic ones.
  • operationId on every operation — explicit via ApiRoute.operationId, otherwise derived from method + path (GET /users/<id>get_users_by_id). OpenAPI client generators now produce usable method names instead of garbage.
  • Typed path parameters via ApiRoute.pathParams: [PathParamSpec('id', type: 'integer')]; undeclared params still default to string.
  • SecurityScheme.apiKey — documents header API-key auth (lock icon in Swagger UI); header name configurable via enableDocs(apiKeyHeader:) to match apiKeyMiddleware.
  • servers in the spec via enableDocs(servers: ['https://api.example.com']) — drives Swagger UI "Try it out" base URLs and client codegen.
  • Pinned, overridable UI assets. Swagger UI (5.32.8) and ReDoc (2.5.3) load from jsdelivr at pinned versions instead of unpkg @latest — an upstream major release can no longer break /docs overnight. Override swaggerUiCssUrl / swaggerUiJsUrl / redocJsUrl to self-host for air-gapped/CSP-restricted deployments.
  • Spec caching/openapi.json is generated once and cached instead of rebuilt per request.
  • Swagger UI enables deepLinking, filter (search box), and tryItOutEnabled by default.

0.4.0 #

Production runtime hardening: graceful shutdown, TLS, proxy-safe rate limiting, API versioning, static files.

Breaking changes #

  • Rate limiter no longer trusts X-Forwarded-For by default. Previously the default key extractor read X-Forwarded-For/X-Real-IP unconditionally — a client could rotate fake header values to dodge the limiter, and all direct clients (no header) shared one 'unknown' bucket, letting a single abuser throttle everyone. The default key is now the real socket IP. Behind a reverse proxy or load balancer, pass trustProxy: true to enableRateLimit / rateLimitMiddleware to key by the first X-Forwarded-For entry.
  • SIGINT/SIGTERM now drain instead of abort. Signal-triggered shutdown previously called stop(force: true), killing in-flight requests — the opposite of what a rolling deploy needs. Signals now trigger a graceful drain bounded by the new DartAPI(shutdownGracePeriod: ...) (default 30 s).
  • Shutdown hooks now run after the drain, so a hook that closes the database can no longer break requests still completing. Previously hooks ran before the listener closed.
  • Removed deprecated JwtService.generateRefreshToken(accessToken: ...) as announced in 0.3.0 — use generateTokenPair instead.

New features #

  • Graceful shutdown: stop() stops accepting connections, waits until every in-flight response is fully written (dart:io's close(force: false) does not), then force-closes stragglers after shutdownGracePeriod.
  • TLS: app.start(securityContext: SecurityContext()..useCertificateChain(...)..usePrivateKey(...)) serves HTTPS natively.
  • API versioning / route prefixes: app.addControllers([...], prefix: '/api/v1') prefixes every HTTP and WebSocket route and is reflected in the OpenAPI spec.
  • Static file serving: app.serveStatic('/public', 'web') (built on shelf_static), with defaultDocument and listDirectories options.
  • clientIp(request, trustProxy: ...) exported helper — spoof-safe client IP resolution for logging, custom rate-limit keys, and audit trails.
  • app.port — the bound port, or null when not running. Combine with start(port: 0) to bind an ephemeral port in tests.
  • InlineController now accepts an optional tag: for OpenAPI grouping, mirroring BaseController.tag.

0.3.0 #

Secure token revocation and refresh rotation.

Breaking changes #

  • JwtService.revokeToken now verifies the token's signature before revoking and returns Future<bool> (true when verified and revoked). Previously it blindly base64-decoded the payload, so an attacker who learned a jti could revoke another user's session with a forged token.
  • TokenStore.revoke gained a {Duration? ttl} parameter — the time remaining until the token's own exp (plus a one-minute clock-skew grace). Backends should use it to expire revocation entries (e.g. Redis SET key 1 EX ttl) so the store does not grow forever. Custom implementations must add the parameter.
  • TokenStore is now an abstract base class with a concrete revokeIfActive(jti, {ttl}) method — extend it rather than implement it. revokeIfActive atomically revokes a jti and reports whether it was still active; distributed backends should override it with an atomic operation (Redis SET NX EX, SQL INSERT ... ON CONFLICT DO NOTHING).
  • generateAccessToken / generateTokenPair no longer allow caller claims to override the protected standard claims (jti, iss, aud, type, iat, exp).

Deprecations #

  • generateRefreshToken({required String accessToken}) is deprecated — deriving a long-lived refresh token from a short-lived access token allows a stolen access token to be upgraded. Use generateTokenPair instead. Will be removed in 0.4.0.

New features #

  • generateTokenPair({required claims}) — issues a matched access/refresh TokenPair directly from claims; the recommended API for login and refresh endpoints.
  • onRefreshTokenReuse callback on JwtService — fires when an already-rotated refresh token is presented again (the classic token-theft signal per the OAuth 2.0 Security BCP), so applications can terminate the whole session.
  • Refresh rotation is now atomic: verifyRefreshToken uses TokenStore.revokeIfActive, so under concurrent use of the same refresh token exactly one caller succeeds (fixes a check-then-revoke race).
  • InMemoryTokenStore prunes expired revocation entries automatically — memory is bounded by the number of tokens revoked within one token lifetime.

Fixes #

  • example/dartapi_core_example.dart refresh endpoint now returns a full new token pair — previously it consumed the single-use refresh token but only returned a new access token, stranding the client.

0.2.0 #

Bug fixes, hardening, and API polish.

Breaking changes #

  • authMiddleware now returns 401 Unauthorized with a WWW-Authenticate: Bearer header when the token is missing or invalid (was 403 Forbidden), matching RFC 6750.
  • Unhandled exceptions in route handlers now return a generic {"error":"Internal Server Error"} body instead of leaking the exception message to the client. The full error and stack trace are logged server-side.
  • queryParam<bool> / pathParam<bool> / header<bool> now accept only true/false/1/0 (case-insensitive) and throw ApiException 400 for anything else (previously any non-'true' value silently became false).

Bug fixes #

  • Fix response serialization for List<Serializable> and Serializable objects nested inside maps/lists — typedHandler can now return Future<List<UserDTO>> directly.
  • Fix globalExceptionMiddleware producing invalid JSON when the error message contains quotes or backslashes.
  • Fix requestIdMiddleware and rateLimitMiddleware corrupting multi-value response headers (multiple Set-Cookie values were joined with commas).
  • Fix setCookie — multiple cookies are now sent as separate Set-Cookie header lines instead of being joined with a newline.
  • Fix cacheMiddleware caching responses that carry Set-Cookie — one client's session cookie could previously be replayed to other clients.
  • Fix rateLimitMiddleware unbounded memory growth — expired buckets are now pruned periodically.
  • Fix FieldSet.validate throwing a cast error (HTTP 500) when a field has the wrong JSON type — now reports a proper 422 field error (must be of type integer).
  • Fix HealthController returning 500 when a health check throws — a throwing check now marks the service degraded with the error message.
  • Fix multipart parsing when the boundary parameter is quoted (boundary="...").
  • Fix JSON array request bodies causing a 500 when a DTO parser expects an object — now returns 400.
  • Fix 204 responses missing the Deprecation header on deprecated routes.
  • compressionMiddleware now sets Vary: Accept-Encoding on compressed responses.

Improvements #

  • DartAPI.start() accepts an address parameter (default 0.0.0.0).
  • New DartAPI.stop({bool force}) — programmatic graceful shutdown: cancels signal watchers, runs onShutdown hooks, then closes the server. Safe to call multiple times.
  • New DartAPI.configureLogging(format:, excludePaths:) — switch the built-in request logging to JSON or silence noisy paths.
  • JwtService now parses RSA PEM keys once and caches them; token id generation reuses a single Random.secure() instance.
  • RangeValidator asserts that at least one bound is provided and no longer produces a "Must be at most null" message.

0.1.9 #

New features.

  • Add bodySizeLimitMiddleware({int maxBytes}) — rejects requests whose Content-Length exceeds the limit with 413 Payload Too Large before the body is read. Default 1 MB. Enable via app.enableBodySizeLimit().
  • Add securityHeadersMiddleware({...}) — adds X-Frame-Options, X-Content-Type-Options, Referrer-Policy, X-XSS-Protection, Permissions-Policy, and optional Content-Security-Policy / Strict-Transport-Security headers. Enable via app.enableSecurityHeaders().
  • Add excludePaths parameter to loggingMiddleware — paths with any matching prefix are silently skipped (e.g. excludePaths: ['/health', '/metrics']).
  • Add HealthCheckResult class and checks parameter to HealthController / app.enableHealthCheck() — run named async health checks; status becomes "degraded" if any check is unhealthy.
  • Add deprecated flag to ApiRoute — emits deprecated: true in the OpenAPI spec and adds a Deprecation: true response header (RFC 8594).
  • Replace threshold-based cache sweep with proper LRU eviction in cacheMiddleware — oldest unused entry is evicted when maxEntries (default 500) is reached; cache hits promote the entry to most-recently-used.
  • Add app.enableBodySizeLimit() and app.enableSecurityHeaders() convenience methods on DartAPI.

0.1.8 #

Bug fixes and hardening.

  • Fix cacheMiddleware memory leak — expired entries are now removed on access and a sweep evicts all stale entries when the cache exceeds 500 keys, preventing unbounded memory growth in long-running servers.
  • Fix HealthController uptime — replaced DateTime.now().difference(startedAt) with Stopwatch.elapsed so reported uptime is immune to system clock adjustments.
  • Fix JwtService._isValidPayload — type-checks every standard claim (sub, jti, iss, aud, type must be String; iat, exp must be int), preventing silent cast errors when a malformed token carries wrong-typed claims.
  • Fix EmailValidator regex — now accepts +, %, _ and other RFC 5321 characters in the local part (e.g. user+tag@example.com).
  • Fix dart analyze — move // ignore: prefer_initializing_formals comments to the correct lines in JwtService constructor initialisers so the linter actually suppresses them.
  • Dependency upgrades: test 1.31.0 → 1.31.1, test_api 0.7.11 → 0.7.12, test_core 0.6.17 → 0.6.18, matcher 0.12.19 → 0.12.20, analyzer 12.1.0 → 13.0.0, vm_service 15.1.0 → 15.2.0.

0.1.7 #

Milestone 5 — OpenAPI Tags.

  • Add tags field to ApiRoute — a List<String> that appears under tags in the generated OpenAPI operation object. Routes with the same tag are grouped together in Swagger UI and ReDoc.
  • Add withTags(List<String>) method to ApiRoute — returns a copy of the route with new tags (all other fields unchanged). Used internally by RouterManager.
  • Add tag getter to BaseController — override in a subclass to automatically apply one tag to every route that declares no explicit tags (e.g. String? get tag => 'Users';). Routes that already have explicit tags are not affected.
  • Update RouterManager.registerController() — stamps the controller's tag onto routes with an empty tags list before collecting them for the spec generator.
  • Add tagDescriptions parameter to OpenApiGenerator, DocsController, and enableDocs() — a Map<String, String> of tag name → description. These appear in the top-level tags array of the OpenAPI spec, adding human-readable descriptions under each group heading in Swagger UI and ReDoc.
  • OpenApiGenerator.generate() now emits tags on each operation when the route has tags and a deduplicated top-level tags array (with optional descriptions) when any route or tagDescriptions entry declares a tag.
  • Update rest_api example — BookController overrides tag => 'Books'; enableDocs() passes tagDescriptions: {'Books': 'CRUD operations for the book catalogue'}.
  • 21 new tests in test/openapi_tags_test.dart (566 total).

0.1.6 #

Milestone 3 — Example Projects.

  • Add example/minimal/ — one-file server with InlineController, health check, and Swagger UI; compiles to a standalone executable.
  • Add example/rest_api/ — full CRUD Books API: FieldSet DTOs, JWT auth, ServiceRegistry, QueryParamSpec, $ref schemas, DartApiTestClient tests (14 tests). Demonstrates every Milestone 1–2 feature end-to-end.
  • Add example/standalone_no_cli/ — annotated starter project equivalent to dartapi create --minimal; explains every file and every decision.
  • Add schemas parameter to enableDocs() — pass Map<String, Map<String, dynamic>> of named schemas; forwarded to DocsController and OpenApiGenerator so components/schemas appears in the spec without constructing the generator manually.
  • Add schemas field to DocsController — enables named schemas when constructing the controller directly without DartAPI.
  • Update README.md — lead with "Getting Started in 5 Minutes (No CLI)", examples table, updated validators table with EnumValidator, QueryParamSpec and $ref OpenAPI docs.

0.1.5 #

Milestone 2 — OpenAPI Spec Quality.

  • Add QueryParamSpec — describes a query parameter for OpenAPI docs (name, type, required, description, defaultValue). Export from barrel.
  • Add queryParams field to ApiRoute — accepts List<QueryParamSpec>. Query params now appear under parameters with in: query in the generated spec alongside path params.
  • Add schemas parameter to OpenApiGenerator — a Map<String, Map<String, dynamic>> of named schemas emitted under components/schemas. Routes can reference them with {'\$ref': '#/components/schemas/Name'}.
  • Add EnumValidator<T>(List<T> values) — validates a closed value set; toSchemaProperties() emits {enum: [...]}. Export from barrel.
  • Add array type support to Field<T>:
    • Field<List<String>> / Field<List<int>> / etc. now produce jsonType: 'array'.
    • New arrayItemType property auto-derived from the generic element type.
    • FieldSet.toJsonSchema() emits items: {type: ...} for array fields.
  • 30 new tests in test/openapi_spec_quality_test.dart (545 total).

0.1.4 #

Milestone 1 — Schema-Validation Sync (FieldSet).

  • Add Field<T> — describes a single DTO field: Dart type (mapped to JSON Schema type), required flag, validators list, optional example and description.
  • Add FieldSet — a declarative map of Fields that provides:
    • validate(Map<String, dynamic> json) — collects ALL field errors before throwing a single ValidationException, replacing the need for manual validateAll boilerplate.
    • toJsonSchema() — derives a complete OpenAPI-compatible JSON Schema (type: object, properties, required array, nullable for optional fields) directly from the field declarations.
  • Add toSchemaProperties() to every built-in validator so schema constraints come from the same source as validation rules:
    • EmailValidator{format: email}. Constructor message is now optional (default: 'Invalid email address').
    • MinLengthValidator(n){minLength: n}
    • MaxLengthValidator(n){maxLength: n}
    • NotEmptyValidator{minLength: 1}
    • RangeValidator(min, max){minimum, maximum}
    • PatternValidator{pattern}
    • UrlValidator{format: uri}
  • Export Field and FieldSet from the dartapi_core barrel.
  • 37 new tests in test/field_set_test.dart (515 total).

0.1.3 #

  • Add comprehensive Books API example (example/dartapi_core_example.dart) demonstrating DartAPI, ServiceRegistry, JwtService, authMiddleware, InMemoryTokenStore, BaseController, ApiRoute, InlineController, Pagination, PaginatedResponse, ApiException, background tasks, per-route caching, health check, Prometheus metrics, and Swagger UI — all in a single runnable file.

0.1.2 #

Milestone 4 — dependency injection via ServiceRegistry.

  • Add ServiceRegistry — type-safe service locator with lazy-singleton instantiation and circular dependency detection.
    • register<T>(T Function(ServiceRegistry)) — lazy singleton factory; factory receives the registry to resolve sub-deps.
    • registerSingleton<T>(T instance) — eager singleton (pre-built instance).
    • get<T>() — resolves and caches on first call; throws StateError for unregistered types or circular deps.
    • isRegistered<T>(), unregister<T>(), clear().
    • Circular dependency detected at resolution time with a full chain in the error message (e.g. A → B → A).
    • Registry is usable again after catching a circular dependency error.
  • Wire ServiceRegistry into DartAPI — convenience methods app.register<T>(), app.registerSingleton<T>(), app.get<T>(), app.isRegistered<T>(), app.registry.
  • 43 new tests in test/service_registry_test.dart covering all registration modes, error paths, circular deps, type safety, and DartAPI integration.
  • Full suite: 478 tests passing.

0.1.1 #

Milestone 2 — auth merged in.

  • Merge all of dartapi_auth into dartapi_core/lib/src/auth/: JwtService (HS256 + RS256), authMiddleware, apiKeyMiddleware, TokenStore, InMemoryTokenStore, TokenHelpers.
  • Add dart_jsonwebtoken ^3.4.1 as a package dependency.
  • Add 70 tests in test/auth_test.dart covering InMemoryTokenStore, JwtService (HS256 + RS256, revocation, rotation, JTI uniqueness), authMiddleware, apiKeyMiddleware, and TokenHelpers.

0.1.0 #

Framework extraction (Milestone 1) — dartapi_core is now a standalone framework.

  • Add DartAPI class — the central application class with opt-in middleware (enableCompression, enableBackgroundTasks, enableTimeout, enableRateLimit, enableMetrics, enableHealthCheck, enableDocs) and lifecycle hooks (onStartup, onShutdown). No longer requires the CLI to use.
  • Add RouterManager — registers BaseController instances with a Shelf Router; collects all ApiRoutes for OpenAPI generation.
  • Add InlineController — define routes inline without creating a dedicated controller class.
  • Add AppConfig — convenience EnvConfig subclass with common fields (port, debug, logLevel, database, JWT, CORS); extend to add project-specific fields.
  • Add loadEnvFile / mergeEnv.env file parsing utilities.
  • Add shelf_router and shelf_cors_headers as package dependencies.

0.0.27 #

  • Upgrade lints from ^5.0.0 to ^6.1.0; fix unnecessary_underscores lint in tests (___)

0.0.26 #

  • Fix compressionMiddleware: responses below the compression threshold had their body stream silently consumed and then returned unmodified — shelf would throw "read method can only be called once" when it tried to send the response. Now rebuilds the response with the already-buffered bytes via response.change(body: bytes).

0.0.25 #

  • ApiRoute handler now passes pre-built shelf.Response objects through unchanged — enables SSE (sseResponse()) and file-download handlers to be used with typedHandler

0.0.24 #

  • Add DartApiTestClient — in-process test client that calls a Shelf Handler directly (no TCP socket); exposes get, post, put, delete, patch and TestResponse with .json<T>()
  • Add LogFormat enum (text | json) to loggingMiddleware — JSON mode emits structured log lines with timestamp, level, method, path, status, duration_ms, and request_id (when requestIdMiddleware has run)
  • Add metricsMiddleware() — records http_requests_total and http_request_duration_seconds histograms per (method, path, status) in a singleton MetricsRegistry
  • Add MetricsController — exposes GET /metrics in Prometheus text format (0.0.4); register via app.enableMetrics()

0.0.23 #

  • Add cacheTtl: Duration? to ApiRoute — opt-in per-route response caching without touching global middleware
  • Add ApiRoute.effectiveMiddlewares getter — returns [cacheMiddleware(ttl: cacheTtl), ...middlewares] when cacheTtl is set; used by RouterManager
  • Update cacheMiddleware docstring with per-route usage examples

0.0.22 #

  • Add ValidationException — carries a list of {field, message} errors for multi-field validation failures
  • Add Map.validateAll(fields) — runs all field validations, collects every failure, then throws ValidationException with the full list (instead of stopping at the first error)
  • ApiRoute handler now catches ValidationException before ApiException and returns {"errors": [...]} with status 422

0.0.21 #

  • Add timeoutMiddleware(Duration) — returns 408 if handler exceeds the timeout
  • Fix: null handler result now returns 204 No Content instead of throwing a 500
  • Improve loggingMiddleware output: [timestamp] METHOD /path STATUS 12ms — removed emoji, added response duration

0.0.20 #

  • Fix: _serialize now handles bool and num responses — returning a bool from a handler no longer throws a 500 "Unable to serialize" error

0.0.19 #

  • Add test/base_controller_test.dart — routes getter, webSocketRoutes default, route callability
  • Add test/logging_middleware_test.dart — pass-through behaviour, method coverage, pipeline composition
  • Extend test/api_route_test.dart — per-route middleware: ordering, short-circuit, header injection

0.0.18 #

  • Add EnvConfig base class — typed env var access (env, envInt, envDouble, envBool) with injectable environment map for testing
  • Add MissingEnvException and InvalidEnvException
  • Add HealthController — exposes GET /health returning {"status":"ok","uptime":"..."}

0.0.17 #

  • Fix: use super parameters in NotEmptyValidator and UrlValidator (linter cleanup)

0.0.16 #

  • Add MinLengthValidator, MaxLengthValidator, NotEmptyValidator, RangeValidator<T extends num>, PatternValidator, UrlValidator
  • Add Pagination — extracts ?page and ?limit from a request with clamping; computes offset
  • Add PaginatedResponseSerializable wrapper that includes a meta block (page, limit, total, totalPages, hasNext, hasPrev)
  • Add SseEvent and sseResponse() for Server-Sent Events streaming

0.0.15 #

  • Add header<T>() extension on Request for typed header extraction (case-insensitive)
  • Add CookieRequestExtensionsrequest.cookies map and request.cookie(name) for reading cookies
  • Add setCookie() helper for attaching Set-Cookie headers to responses (supports maxAge, path, domain, sameSite, httpOnly, secure)
  • Add cacheMiddleware — in-memory GET response cache with configurable TTL and custom key extractor; adds X-Cache: HIT/MISS headers

0.0.14 #

  • Add multipartFiles(), file(), formFields() extensions on Request for multipart/form-data parsing
  • Add UploadedFile with bytes, filename, contentType, text, and isFile
  • Add BackgroundTaskQueue, backgroundTaskMiddleware(), and Request.backgroundTasks for post-response async work
  • Add WebSocketRoute for WebSocket endpoints alongside HTTP routes
  • BaseController now has webSocketRoutes (default empty list)
  • New dependencies: mime, shelf_web_socket, web_socket_channel

0.0.13 #

  • Add rateLimitMiddleware — token-bucket rate limiter keyed by IP (or custom key); returns 429 with Retry-After and X-RateLimit-* headers
  • Add requestIdMiddleware — attaches X-Request-Id to every request/response; propagates existing IDs; stores ID in request.context['requestId']
  • Add compressionMiddleware — gzip-compresses responses above a configurable threshold when client sends Accept-Encoding: gzip

0.0.12 #

  • Improve README: update version snippet, improve formatting

0.0.11 #

  • Fix type-mismatch error message in verifyKey: now uses friendly JSON type names (string, integer, number, boolean) instead of Dart type names

0.0.10 #

  • Swagger UI: bearerAuth security scheme is now always present in the spec so the Authorize button always appears
  • Swagger UI: persistAuthorization: true — entered tokens survive page refreshes (stored in localStorage)

0.0.9 #

  • Add OpenApiGenerator — generates an OpenAPI 3.0 spec from a list of ApiRoutes
  • Add DocsController — serves GET /openapi.json, GET /docs (Swagger UI), GET /redoc (ReDoc)
  • Add SecurityScheme enum with bearer value; ApiRoute now accepts security: [SecurityScheme.bearer]
  • Add contentType field on ApiRoute (default 'application/json'); used for HTML doc routes
  • Add tests for all new OpenAPI types (23 additional tests)

0.0.8 #

  • Expand test suite: comprehensive tests for ApiRoute, RequestExtensions (pathParam/queryParam), MapExtensions, and globalExceptionMiddleware

0.0.7 #

  • Add pathParam<T>() extension on Request for typed path parameter extraction
  • Add queryParam<T>() extension on Request for typed query parameter extraction with optional default values
  • Add statusCode field on ApiRoute (default 200) for custom success response codes (e.g. 201, 204)
  • Add globalExceptionMiddleware for app-level exception handling

0.0.6 #

  • Add ApiException class for returning specific HTTP error status codes from handlers and validators
  • Fix FormatException (malformed JSON body) now returns 400 Bad Request instead of 500
  • Fix validation errors from verifyKey() now return 422 Unprocessable Entity instead of 500
  • ApiException is exported from the package

0.0.5 #

  • Improved Logging

0.0.4 #

  • Improve code documentation

0.0.3 #

  • Add Email Validator

0.0.2 #

  • Change License
  • Add Middelware
  • Add Validators
  • Enhance Key Verification with Validators

0.0.1 #

  • Initial version.
1
likes
160
points
114
downloads

Documentation

API reference

Publisher

verified publisherakashgk.com

Weekly Downloads

Core utilities for building typed, structured REST APIs in Dart, including routing, validation, and middleware support.

Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

dart_jsonwebtoken, mime, shelf, shelf_cors_headers, shelf_router, shelf_static, shelf_web_socket, web_socket_channel

More

Packages that depend on dartapi_core