Services
Services are the building blocks of PrioStack applications. Each service is a self-contained unit of functionality that can expose APIs, handle business logic, and respond to events. Services communicate with each other to create complete applications within bundles.
💡 Key Concept: Services follow the single responsibility principle. Each service should do one thing well and be independently deployable.
Service Definition
Services are defined using YAML configuration files. Each service file describes the service's capabilities, API endpoints, intents, and dependencies.
Basic Service Structure
name: my-service
description: A service that handles user authentication
version: 1.0.0
# Optional: API endpoints
api:
basePath: "/api/v1/auth"
endpoints:
- name: login
method: POST
path: "/login"
to: wasm:auth:loginUser
# Optional: Reactive intents
intents:
- name: sessionCleanup
whenSensor: userInactive
toFunc: wasm:auth:cleanupSession
primitiveIntent: cleanup
# Optional: Goals and metrics
goals:
- name: responseTime
metric: latency
target: "< 500ms"
description: API response time should be under 500ms
Service Configuration Fields
Basic Information
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Unique service identifier within the bundle |
description |
string | No | Human-readable description of the service |
version |
string | No | Service version (semantic versioning) |
API Endpoints
Services can expose REST API endpoints that other services or external clients can call. Endpoints are defined with HTTP methods, paths, and handlers.
Endpoint Configuration
| Field | Type | Description |
|---|---|---|
name |
string | Unique endpoint name within the service |
method |
string | HTTP method (GET, POST, PUT, DELETE, PATCH) |
path |
string | URL path relative to basePath |
to |
string | Handler function (wasm:service:function or func:function) |
description |
string | Optional description of the endpoint |
Example API Configuration
api:
basePath: "/api/v1/users"
endpoints:
- name: getUser
method: GET
path: "/:userId"
to: wasm:users:getUserById
description: Retrieve user information
- name: createUser
method: POST
path: "/"
to: wasm:users:createNewUser
description: Create a new user account
- name: updateUser
method: PUT
path: "/:userId"
to: wasm:users:updateUserProfile
description: Update user profile information
Service Intents
Intents define how services react to events and sensors. They enable services to be event-driven and respond automatically to changes in the system.
Intent Configuration
| Field | Type | Description |
|---|---|---|
name |
string | Unique intent name within the service |
whenSensor |
string | Sensor that triggers this intent |
toFunc |
string | Handler function to execute |
primitiveIntent |
string | Type of intent (stateMutation, validation, workflow, etc.) |
cooldown |
duration | Minimum time between executions |
retries |
number | Number of retry attempts on failure |
Goals and Metrics
Goals define success criteria for your service using measurable metrics. This framework is designed for future monitoring and alerting capabilities.
Goal Configuration
| Field | Type | Description |
|---|---|---|
name |
string | Unique goal name within the service |
metric |
string | Metric to measure (latency, throughput, errorRate, etc.) |
target |
string | Target value or range for the metric |
description |
string | Description of the goal |
Example Goals
goals:
- name: apiResponseTime
metric: latency
target: "< 200ms"
description: API responses should be under 200ms
- name: errorRate
metric: errorRate
target: "< 0.1%"
description: Error rate should be below 0.1%
- name: throughput
metric: throughput
target: "> 1000 req/min"
description: Service should handle at least 1000 requests per minute
Service Dependencies
Services can declare dependencies on other services within the same bundle. PrioStack uses these dependencies to determine the correct startup order.
⚠️ Important: Dependencies must not create circular references. Service A cannot depend on Service B if Service B depends on Service A.
Defining Dependencies
Dependencies are declared using the dependsOn field in the service configuration:
name: order-service
description: Handles order processing
dependsOn:
- payment-service
- inventory-service
# ... rest of service configuration
Service Lifecycle
Services go through several phases during their lifecycle:
1. Configuration
Service configuration is loaded and validated. Dependencies are checked to ensure all required services are available.
2. Initialization
WASM modules are loaded and initialized. API endpoints are registered with the routing system.
3. Runtime
Service is actively running, handling requests and responding to intents. The service participates in the bundle's overall functionality.
4. Shutdown
Service is gracefully stopped. Resources are cleaned up and connections are closed.
Best Practices
Service Design
- Single Responsibility: Each service should have one clear purpose
- Loose Coupling: Services should communicate through well-defined APIs
- Independent Deployment: Services should be deployable independently
API Design
- RESTful: Use standard HTTP methods and meaningful resource paths
- Versioning: Include API versioning in basePath when needed
- Documentation: Always include descriptions for endpoints
Intent Design
- Event-Driven: Use intents for reactive behavior, not synchronous calls
- Idempotent: Intents should be safe to execute multiple times
- Fast: Keep intent handlers lightweight and responsive
✅ Pro Tip: Start with simple services and add complexity gradually. You can always refactor and split services later as your application grows.