ESC

Type to search...

FAQ

Frequently asked questions about EVOID.

General

What is IOP?

Intent-Oriented Programming is a paradigm where data declares what it needs. The runtime handles how. Instead of writing “how to save a user,” you declare “this is critical data” and the runtime adds encryption, audit logging, and replication automatically.

When should I use EVOID?

Use EVOID when:

  • Multiple services need to communicate
  • Different data needs different infrastructure (payments need PostgreSQL, sessions need Redis)
  • You want pipeline-based extensibility
  • You need typed, validated processing chains

When should I NOT use EVOID?

EVOID is overkill for:

  • Simple single-file scripts
  • Tiny APIs with < 5 endpoints
  • Projects where you don’t need pipeline extensibility

Is EVOID production-ready?

EVOID is in beta (v0.6.x). The core is stable, minimal dependencies, all tests passing. APIs may change before v1.0. Pin your version in production.

Technical

How does EVOID differ from middleware?

Traditional middleware wraps the entire request/response. EVOID processors run as part of a pipeline, with access to shared state (ctx.state). Processors are composable, replaceable, and can be injected at any point.

Can I use EVOID with FastAPI?

Yes. EVOID complements FastAPI. Use FastAPI for HTTP endpoints and EVOID for internal service communication, validation pipelines, and inter-service messaging.

What’s the performance overhead?

EVOID pipeline execution has near-zero overhead. The fast path (no inspection, no timeout) runs at ~10K ops/s on a 5-processor pipeline. Inspection and timeout add minimal cost.

How do I switch from SQLite to PostgreSQL?

Change evoid.toml and run evo sync:

[engines]
storage = "sqlalchemy"
evo sync

Zero code changes to your business logic.

How do I add authentication?

Use the built-in auth_checker processor with the simple auth engine:

from evoid.processors import auth_checker
from evoid.core.extend import before

before("GET:/users/{id}", "auth_checker")

Or create a custom processor (no plugin needed):

from evoid.core import Context, register_processor

async def check_auth(ctx: Context) -> dict:
    token = ctx.intent.metadata.get("headers", {}).get("authorization")
    if not token:
        raise ValueError("Unauthorized")
    ctx.state["user"] = verify_token(token)
    return {"authenticated": True}

register_processor("check_auth", check_auth)

How do I handle errors?

Raise exceptions in processors. The pipeline stops and returns a failed Result:

result = await execute(intent)

if not result.success:
    print(f"Error: {result.error}")
    print(f"Failed after: {result.processors}")

For non-critical errors, append to ctx.errors:

ctx.errors.append(ValidationError("optional check failed"))
# Pipeline continues

How do I test my processors?

import asyncio
from evoid.core import Context, Intent, Level, register_processor

async def my_processor(ctx: Context) -> dict:
    return {"valid": True}

async def test_my_processor():
    intent = Intent(name="test", level=Level.STANDARD)
    ctx = Context(intent=intent, state={"data": "hello"})

    result = await my_processor(ctx)

    assert result["valid"] is True

asyncio.run(test_my_processor())

CLI

How do I create a project?

evo init my-api
cd my-api

How do I add a service?

evo service new api

How do I run my service?

evo service run api

How do I sync dependencies?

evo sync

This reads evoid.toml and installs required packages.