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.

Next: Intents →