Skip to content

Latest commit

 

History

History
396 lines (291 loc) · 22.1 KB

File metadata and controls

396 lines (291 loc) · 22.1 KB

Requirements Document: Sweet API Framework

Introduction

Sweet is a high-performance API server framework written in Mojo that targets sub-millisecond latency and 1M+ requests per second throughput. The framework combines AOT compilation, thread-per-core architecture, SIMD acceleration, and Railway Oriented Programming to deliver extreme performance while maintaining type safety and excellent developer ergonomics. This document specifies the functional and non-functional requirements for developers building high-performance APIs with Sweet.

Glossary

  • Sweet: The high-performance API framework being specified
  • Handler: A function that processes HTTP requests and returns responses
  • Middleware: A component that intercepts and processes requests/responses in the pipeline
  • Router: The component that matches incoming request paths to handlers
  • Reactor: The async I/O event loop managing network operations
  • Parser: The HTTP protocol parser that converts raw bytes to structured requests
  • Arena: A memory allocator that provides O(1) bulk deallocation
  • ROP: Railway Oriented Programming, an error handling pattern using Result types
  • SIMD: Single Instruction Multiple Data, vectorized CPU instructions
  • AOT: Ahead-of-Time compilation
  • SPSC: Single Producer Single Consumer queue
  • DFA: Deterministic Finite Automaton
  • StringRef: A zero-copy reference to a string in a buffer
  • Plugin: An encapsulated, reusable component that extends framework functionality
  • Task_Queue: The background task processing system
  • Cron_Scheduler: The time-based job scheduling system
  • Validator: A component that checks data against schema constraints
  • Serializer: A component that converts data structures to/from JSON

Requirements

Requirement 1: HTTP Request Processing

User Story: As an API developer, I want to handle HTTP requests efficiently, so that my API can serve high traffic with low latency.

Acceptance Criteria

  1. WHEN a valid HTTP/1.1 request is received, THE Parser SHALL parse it into an HttpRequest structure
  2. WHEN parsing HTTP requests, THE Parser SHALL use zero-copy StringRef to avoid allocations
  3. WHEN parsing HTTP requests, THE Parser SHALL use SIMD instructions for delimiter detection
  4. WHEN an HTTP request is malformed, THE Parser SHALL return a descriptive ParseError
  5. THE Parser SHALL support GET, POST, PUT, DELETE, and PATCH methods
  6. WHEN parsing headers, THE Parser SHALL validate that all header names and values are valid UTF-8
  7. WHEN parsing is complete, THE Parser SHALL extract query parameters from the path

Requirement 2: Route Matching and Dispatching

User Story: As an API developer, I want to define routes with path parameters, so that I can build RESTful APIs with clean URLs.

Acceptance Criteria

  1. WHEN a route is registered, THE Router SHALL compile it into a radix trie at build time
  2. WHEN an incoming request path matches a registered route, THE Router SHALL return the corresponding handler and extracted parameters
  3. WHEN a request path does not match any route, THE Router SHALL return a RouteError
  4. THE Router SHALL support static routes (e.g., /users, /posts)
  5. THE Router SHALL support parameterized routes (e.g., /users/:id, /posts/:slug)
  6. THE Router SHALL support wildcard routes (e.g., /static/*)
  7. WHEN extracting path parameters, THE Router SHALL populate the RouteParams dictionary with parameter names and values
  8. THE Router SHALL perform route matching in O(path_length) time complexity

Requirement 3: Request Validation

User Story: As an API developer, I want to validate request data against schemas, so that invalid data is rejected before reaching my business logic.

Acceptance Criteria

  1. WHEN a validation schema is defined, THE Validator SHALL compile it at build time
  2. WHEN validating a request, THE Validator SHALL check all fields against their constraints
  3. WHEN validation fails, THE Validator SHALL return a ValidationError with field-level details
  4. WHEN validation succeeds, THE Validator SHALL return the validated data structure
  5. THE Validator SHALL support string constraints (min_length, max_length, pattern)
  6. THE Validator SHALL support integer constraints (min_value, max_value)
  7. THE Validator SHALL support nested object validation
  8. THE Validator SHALL support array validation
  9. THE Validator SHALL generate validation code at compile time for zero runtime cost

Requirement 4: JSON Serialization

User Story: As an API developer, I want to serialize and deserialize JSON efficiently, so that my API can handle JSON payloads with minimal overhead.

Acceptance Criteria

  1. WHEN serializing a data structure, THE Serializer SHALL produce valid JSON
  2. WHEN deserializing JSON, THE Serializer SHALL parse it into the target data structure
  3. WHEN serializing strings, THE Serializer SHALL properly escape special characters
  4. THE Serializer SHALL use SIMD instructions for delimiter detection during parsing
  5. THE Serializer SHALL use SIMD instructions for string escaping during serialization
  6. FOR ALL valid data structures, THE Serializer SHALL satisfy the round-trip property: deserialize(serialize(obj)) equals obj
  7. WHEN JSON is invalid, THE Serializer SHALL return a descriptive JsonError

Requirement 5: Middleware Pipeline

User Story: As an API developer, I want to use middleware for cross-cutting concerns, so that I can implement logging, authentication, and CORS without duplicating code.

Acceptance Criteria

  1. WHEN middleware is registered, THE Middleware_Chain SHALL execute it in registration order
  2. WHEN processing a request, THE Middleware_Chain SHALL invoke on_request hooks before routing
  3. WHEN processing a request, THE Middleware_Chain SHALL invoke pre_handler hooks before the handler
  4. WHEN processing a response, THE Middleware_Chain SHALL invoke on_response hooks in reverse order
  5. WHEN an error occurs, THE Middleware_Chain SHALL invoke on_error hooks to handle the error
  6. WHEN middleware returns an error, THE Middleware_Chain SHALL short-circuit and skip remaining middleware
  7. THE Middleware_Chain SHALL allow middleware to transform requests and responses
  8. THE Middleware_Chain SHALL allow middleware to share state via the request context

Requirement 6: Error Handling

User Story: As an API developer, I want explicit error handling with Railway Oriented Programming, so that errors are handled consistently and safely.

Acceptance Criteria

  1. THE Sweet SHALL use Result types for all operations that can fail
  2. WHEN a Result is Ok, THE Sweet SHALL contain a valid success value
  3. WHEN a Result is Err, THE Sweet SHALL contain an error with a descriptive message
  4. THE Result type SHALL support map operations for transforming success values
  5. THE Result type SHALL support and_then operations for chaining fallible operations
  6. WHEN an error occurs in a handler, THE Sweet SHALL propagate it through the middleware chain
  7. WHEN an error reaches the top level, THE Sweet SHALL convert it to an appropriate HTTP error response
  8. THE Sweet SHALL map ErrorKind.NotFound to HTTP 404
  9. THE Sweet SHALL map ErrorKind.BadRequest to HTTP 400
  10. THE Sweet SHALL map ErrorKind.Unauthorized to HTTP 401
  11. THE Sweet SHALL map ErrorKind.InternalError to HTTP 500

Requirement 7: Memory Management

User Story: As an API developer, I want efficient memory management, so that my API doesn't waste resources on allocation overhead.

Acceptance Criteria

  1. WHEN processing a request, THE Arena SHALL allocate memory from a pre-allocated buffer
  2. WHEN an allocation exceeds arena capacity, THE Arena SHALL return an error
  3. WHEN request processing completes, THE Arena SHALL reset in O(1) time
  4. THE Arena SHALL prevent buffer overflows by bounds-checking all allocations
  5. WHEN the arena is reset, THE Arena SHALL set its offset to zero
  6. THE Sweet SHALL allocate less than 1KB of memory per typical request

Requirement 8: Async I/O Operations

User Story: As an API developer, I want non-blocking I/O, so that my API can handle many concurrent connections efficiently.

Acceptance Criteria

  1. WHERE io_uring is available, THE Reactor SHALL use io_uring for async I/O operations
  2. WHERE io_uring is not available, THE Reactor SHALL fall back to epoll
  3. WHEN a socket is ready for reading, THE Reactor SHALL invoke the registered read handler
  4. WHEN a socket is ready for writing, THE Reactor SHALL invoke the registered write handler
  5. WHEN a connection is closed, THE Reactor SHALL invoke the close handler and clean up resources
  6. THE Reactor SHALL submit multiple I/O operations in batches to reduce syscall overhead
  7. THE Reactor SHALL configure sockets with TCP_NODELAY to minimize latency
  8. THE Reactor SHALL configure sockets with TCP_QUICKACK to minimize latency
  9. THE Reactor SHALL use SO_REUSEPORT to distribute connections across worker cores

Requirement 9: Thread-Per-Core Architecture

User Story: As an API developer, I want predictable performance under load, so that my API doesn't suffer from lock contention or cache coherency issues.

Acceptance Criteria

  1. WHEN the server starts, THE Sweet SHALL create one worker thread per configured core
  2. WHEN a connection arrives, THE Kernel SHALL distribute it to a worker core via SO_REUSEPORT
  3. WHILE processing a request, THE Worker SHALL use only its own memory and resources
  4. THE Sweet SHALL ensure no cross-core synchronization is required for request processing
  5. WHEN multiple cores are active, THE Sweet SHALL scale linearly with core count
  6. THE Sweet SHALL maintain separate memory arenas per core
  7. THE Sweet SHALL maintain separate connection pools per core

Requirement 10: Background Task Processing

User Story: As an API developer, I want to offload long-running work to background tasks, so that my API responses remain fast.

Acceptance Criteria

  1. WHEN a task is enqueued, THE Task_Queue SHALL accept it without blocking the request
  2. WHERE the system has one core, THE Task_Queue SHALL use a local deque for task storage
  3. WHERE the system has multiple cores, THE Task_Queue SHALL use SPSC buffers with Redis fallback
  4. WHEN a task is dequeued, THE Task_Executor SHALL invoke the registered handler for that task type
  5. WHEN a task fails, THE Task_Executor SHALL retry it up to max_retries times
  6. WHEN a task exceeds max_retries, THE Task_Executor SHALL move it to the dead letter queue
  7. WHEN retrying a task, THE Task_Executor SHALL apply exponential backoff
  8. THE Task_Queue SHALL guarantee at-least-once delivery of tasks

Requirement 11: Scheduled Job Execution

User Story: As an API developer, I want to schedule recurring jobs with cron expressions, so that I can automate periodic tasks.

Acceptance Criteria

  1. WHEN a cron job is registered, THE Cron_Scheduler SHALL parse and validate the cron expression
  2. WHEN a cron job is registered, THE Cron_Scheduler SHALL calculate the next execution time
  3. WHEN a cron job's execution time arrives, THE Cron_Scheduler SHALL invoke the job handler
  4. WHEN a cron job completes, THE Cron_Scheduler SHALL calculate the next execution time and reschedule it
  5. THE Cron_Scheduler SHALL use a min-heap to efficiently determine the next job to execute
  6. WHEN a cron job fails, THE Cron_Scheduler SHALL log the error and continue with the schedule
  7. THE Cron_Scheduler SHALL persist job state to the configured job store
  8. THE Cron_Scheduler SHALL support standard cron expression fields (minute, hour, day, month, weekday)

Requirement 12: HTTP Client

User Story: As an API developer, I want to make HTTP requests to external services, so that my API can integrate with other systems.

Acceptance Criteria

  1. WHEN making an HTTP request, THE Http_Client SHALL reuse connections from the connection pool
  2. WHEN no idle connection exists, THE Http_Client SHALL create a new connection
  3. WHEN a connection is idle beyond the timeout, THE Http_Client SHALL close it
  4. THE Http_Client SHALL limit connections per host to max_connections_per_host
  5. THE Http_Client SHALL support GET, POST, PUT, and DELETE methods
  6. WHEN a request times out, THE Http_Client SHALL return a timeout error
  7. THE Http_Client SHALL perform DNS resolution asynchronously using a thread pool
  8. THE Http_Client SHALL cache DNS results to avoid repeated lookups

Requirement 13: Structured Logging

User Story: As an API developer, I want structured logging with key-value fields, so that I can easily search and analyze logs.

Acceptance Criteria

  1. WHEN logging a message, THE Logger SHALL include a timestamp
  2. WHEN logging a message, THE Logger SHALL include the log level
  3. WHEN logging a message, THE Logger SHALL include the source location
  4. WHEN logging a message, THE Logger SHALL include any provided key-value fields
  5. THE Logger SHALL support log levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
  6. WHEN the log level is below the configured threshold, THE Logger SHALL skip logging
  7. THE Logger SHALL use a memory arena for zero-allocation logging
  8. THE Logger SHALL buffer log writes for performance
  9. THE Logger SHALL support multiple log sinks (stdout, file, network)

Requirement 14: Plugin System

User Story: As an API developer, I want to use plugins for common functionality, so that I don't have to implement features like CORS and authentication from scratch.

Acceptance Criteria

  1. WHEN a plugin is registered, THE Plugin_Registry SHALL invoke its register method
  2. WHEN the server starts, THE Plugin_Registry SHALL invoke on_startup for all plugins
  3. WHEN the server stops, THE Plugin_Registry SHALL invoke on_shutdown for all plugins
  4. THE Plugin SHALL be able to register routes during registration
  5. THE Plugin SHALL be able to register middleware during registration
  6. THE Plugin SHALL be able to register lifecycle hooks during registration
  7. THE Sweet SHALL provide built-in plugins for CORS, JWT authentication, and rate limiting

Requirement 15: Dependency Injection

User Story: As an API developer, I want dependency injection for services, so that my handlers can access databases and caches without manual wiring.

Acceptance Criteria

  1. WHEN a dependency is registered as a singleton, THE DI_Container SHALL create it once and reuse it
  2. WHEN a dependency is registered as a factory, THE DI_Container SHALL create a new instance on each resolution
  3. WHEN a handler requests a dependency, THE DI_Container SHALL resolve it at compile time where possible
  4. THE Sweet SHALL support functional dependency injection via Dependencies parameter
  5. THE Sweet SHALL support decorator-based dependency injection via @inject annotation
  6. WHEN a dependency cannot be resolved, THE DI_Container SHALL return a descriptive error

Requirement 16: OpenAPI Documentation

User Story: As an API developer, I want automatic OpenAPI documentation, so that API consumers can understand my endpoints without manual documentation.

Acceptance Criteria

  1. WHEN routes are registered, THE OpenAPI_Generator SHALL extract route metadata
  2. WHEN generating OpenAPI spec, THE OpenAPI_Generator SHALL include all registered routes
  3. WHEN generating OpenAPI spec, THE OpenAPI_Generator SHALL include path parameters
  4. WHEN generating OpenAPI spec, THE OpenAPI_Generator SHALL include request body schemas
  5. WHEN generating OpenAPI spec, THE OpenAPI_Generator SHALL include response schemas
  6. THE Sweet SHALL serve the OpenAPI specification at /openapi.json
  7. THE OpenAPI_Generator SHALL produce valid OpenAPI 3.0 JSON

Requirement 17: Configuration Management

User Story: As an API developer, I want to configure server settings, so that I can tune performance and behavior for my deployment environment.

Acceptance Criteria

  1. WHEN creating a server configuration, THE Sweet SHALL validate all settings
  2. IF the port is outside the range 1-65535, THEN THE Sweet SHALL return a validation error
  3. IF num_workers is less than 1, THEN THE Sweet SHALL return a validation error
  4. IF TLS is enabled but cert/key paths are missing, THEN THE Sweet SHALL return a validation error
  5. THE Sweet SHALL support configuration of host, port, and num_workers
  6. THE Sweet SHALL support configuration of io_uring_entries, tcp_nodelay, tcp_quickack, so_reuseport, and backlog
  7. THE Sweet SHALL support configuration of TLS certificate and key paths

Requirement 18: Performance Targets

User Story: As an API developer, I want sub-millisecond latency, so that my API can meet strict SLA requirements.

Acceptance Criteria

  1. THE Sweet SHALL achieve p99 latency under 1 millisecond for simple API operations
  2. THE Sweet SHALL achieve throughput of 60,000-100,000 requests per second per core
  3. THE Sweet SHALL scale linearly with core count up to 16+ cores
  4. THE Sweet SHALL use less than 1KB of memory per typical request
  5. THE Sweet SHALL parse HTTP requests in 10-20 microseconds using SIMD
  6. THE Sweet SHALL match routes in 5-10 microseconds using radix trie
  7. THE Sweet SHALL serialize JSON responses in 20-50 microseconds using SIMD

Requirement 19: Security

User Story: As an API developer, I want secure input handling, so that my API is protected against common attacks.

Acceptance Criteria

  1. WHEN validating input, THE Sweet SHALL enforce maximum header size of 8KB
  2. WHEN validating input, THE Sweet SHALL enforce maximum body size of 10MB (configurable)
  3. WHEN validating input, THE Sweet SHALL enforce maximum path length of 2KB
  4. WHEN validating input, THE Sweet SHALL enforce maximum query string length of 4KB
  5. WHEN validating input, THE Sweet SHALL enforce maximum number of headers of 100
  6. THE Sweet SHALL validate all string inputs are valid UTF-8
  7. THE Sweet SHALL bounds-check all buffer accesses to prevent overflows
  8. WHEN serializing JSON, THE Sweet SHALL escape special characters to prevent injection
  9. THE Sweet SHALL provide middleware hooks for authentication and authorization
  10. THE Sweet SHALL support rate limiting via middleware

Requirement 20: Error Recovery

User Story: As an API developer, I want graceful error handling, so that my API continues serving requests even when errors occur.

Acceptance Criteria

  1. WHEN an HTTP parse error occurs, THE Sweet SHALL return HTTP 400 and continue processing
  2. WHEN a route is not found, THE Sweet SHALL return HTTP 404 and continue processing
  3. WHEN validation fails, THE Sweet SHALL return HTTP 422 with field-level errors
  4. WHEN a handler raises an error, THE Sweet SHALL return HTTP 500 and log the error
  5. WHEN an I/O error occurs, THE Sweet SHALL close the connection and clean up resources
  6. WHEN arena exhaustion occurs, THE Sweet SHALL return HTTP 500 and reset the arena
  7. WHEN a background task fails, THE Sweet SHALL retry it with exponential backoff
  8. WHEN a cron job fails, THE Sweet SHALL log the error and continue with the schedule
  9. WHEN any error occurs, THE Sweet SHALL reset the memory arena to prevent leaks

Requirement 21: Testing Support

User Story: As an API developer, I want comprehensive testing capabilities, so that I can ensure my API works correctly.

Acceptance Criteria

  1. THE Sweet SHALL provide unit testing support for all components
  2. THE Sweet SHALL provide property-based testing for parsers, routers, and serializers
  3. THE Sweet SHALL provide integration testing support for full request-response cycles
  4. THE Sweet SHALL provide benchmarking tools for performance testing
  5. THE Sweet SHALL achieve greater than 90% line coverage in tests
  6. THE Sweet SHALL achieve greater than 85% branch coverage in tests
  7. THE Sweet SHALL test all error paths and recovery scenarios

Requirement 22: Developer Experience

User Story: As an API developer, I want intuitive APIs and helpful error messages, so that I can be productive quickly.

Acceptance Criteria

  1. WHEN a route is registered with an invalid pattern, THE Sweet SHALL provide a descriptive compile-time error
  2. WHEN validation fails, THE Sweet SHALL provide field-level error messages
  3. WHEN a handler returns an error, THE Sweet SHALL include the error message in logs
  4. THE Sweet SHALL provide clear examples for common use cases
  5. THE Sweet SHALL provide comprehensive API documentation
  6. THE Sweet SHALL use type-safe APIs to prevent runtime errors
  7. THE Sweet SHALL provide helpful compiler errors for misuse

Requirement 23: Deployment Support

User Story: As an API developer, I want easy deployment options, so that I can run my API in various environments.

Acceptance Criteria

  1. THE Sweet SHALL compile to a single native binary with no runtime dependencies
  2. THE Sweet SHALL support running behind a reverse proxy for TLS termination
  3. THE Sweet SHALL support containerized deployment with Docker
  4. THE Sweet SHALL support orchestration with Kubernetes
  5. THE Sweet SHALL provide health check endpoints for load balancers
  6. THE Sweet SHALL support graceful shutdown to drain in-flight requests
  7. THE Sweet SHALL support configuration via environment variables

Requirement 24: Monitoring and Observability

User Story: As an API developer, I want built-in metrics and tracing, so that I can monitor my API's health and performance.

Acceptance Criteria

  1. THE Sweet SHALL expose request latency histograms (p50, p95, p99, p999)
  2. THE Sweet SHALL expose requests per second metrics per core
  3. THE Sweet SHALL expose memory arena utilization metrics
  4. THE Sweet SHALL expose connection pool statistics
  5. THE Sweet SHALL expose background task queue depth metrics
  6. THE Sweet SHALL expose error rates by error type
  7. THE Sweet SHALL support exporting metrics to Prometheus
  8. THE Sweet SHALL support distributed tracing with trace IDs

Requirement 25: Cross-Platform Support

User Story: As an API developer, I want to develop on macOS and deploy on Linux, so that I can use my preferred development environment.

Acceptance Criteria

  1. THE Sweet SHALL run on Linux with full feature support
  2. THE Sweet SHALL run on macOS with epoll fallback for development
  3. THE Sweet SHALL require x86_64 CPU with AVX2 support for SIMD operations
  4. THE Sweet SHALL require Linux kernel 5.1+ for io_uring support
  5. THE Sweet SHALL fall back to epoll on kernels without io_uring
  6. THE Sweet SHALL require Mojo compiler version 0.26.3 or later