Files
apophis-fastify/docs/attic/MULTI_FRAMEWORK_FEASIBILITY.md

13 KiB

Multi-Framework Feasibility and Roadmap

Status: Proposal Audience: APOPHIS maintainers and platform strategy owners Purpose: assess whether APOPHIS can expand beyond Fastify into Express, Python, and Go without turning into a platform rewrite

Current decision:

  • APOPHIS is remaining Node-first and Fastify-first for now.
  • There is no active multi-language expansion roadmap at this time.
  • This document is retained as feasibility analysis, not as an execution commitment.
  • Express is the only plausible near-term adapter candidate, and even that is optional rather than planned.

1. Executive Summary

Short answer:

  • Express: feasible
  • Python: feasible only through a narrower first step
  • Go: feasible only later, and only with a smaller ambition than a native feature-parity port

The practical recommendation is:

  1. extract a framework-neutral core inside the current Node codebase
  2. ship a CLI/spec-first mode that can hit any running server from an OpenAPI document
  3. validate the adapter seam with Express next
  4. defer native Python and Go adapters until the core and CLI are proven

If the goal is “Fastify + Express + generic spec-driven CLI,” this is tractable.

If the goal is “feature-parity native integrations for Fastify, Express, Python, and Go all at once,” that is too large and should be deferred.

For the current product strategy, this means:

  • do not start multi-language work now
  • do not let speculative portability drive the core redesign
  • only revisit Express later if the Node adapter seam becomes cheap and the Fastify product is already strong

2. Why This Is Plausible At All

APOPHIS already has a meaningful split between:

  • behavioral contract semantics
  • execution and test orchestration
  • framework integration

The following parts are reusable after adapter extraction:

  • APOSTL parser and evaluator
  • contract extraction from schema annotations
  • schema-to-contract inference
  • state/resource/invariant helpers
  • chaos engine and much of the reporting stack

The following parts are currently Fastify-shaped:

  • route discovery through onRoute
  • request execution through fastify.inject()
  • runtime validation hooks bound to Fastify lifecycle
  • OpenAPI/spec exposure through @fastify/swagger
  • cleanup and route storage assumptions

That means APOPHIS is not currently framework-agnostic, but it is also not trapped in Fastify everywhere.

3. The Current Coupling Problem

The real coupling is not just “HTTP framework.”

The real couplings are:

  1. route discovery
  2. schema and annotation access
  3. test execution transport
  4. runtime middleware or hook semantics
  5. OpenAPI acquisition

Fastify makes these unusually convenient because it has:

  • route-local schemas
  • predictable registration hooks
  • inject() for in-process execution
  • strong plugin lifecycle hooks

Express, Python, and Go differ in route metadata access, request injection support, and lifecycle hook semantics.

That is why a direct “port the plugin” mindset is dangerous.

4. Prior Systems That Validate Parts Of The Model

These systems show that the general space is real.

4.1 JavaScript / Node

  • Dredd: language-agnostic CLI validating API behavior against OpenAPI or Swagger
  • express-openapi-validator: OpenAPI-based request and response validation middleware for Express
  • openapi-backend: framework-agnostic OpenAPI routing, validation, and mocking in Node

What this validates:

  • spec-driven runtime behavior is normal in Node
  • CLI-driven cross-framework contract testing is viable
  • APOPHIS does not need to remain Fastify-only to stay coherent

4.2 Python

  • Connexion: spec-first Python framework from OpenAPI
  • openapi-core: framework-agnostic request and response validation against OpenAPI
  • Schemathesis: OpenAPI-driven property-based testing and stateful API testing

What this validates:

  • OpenAPI-driven request and response validation is mature in Python
  • property-based testing from schemas is already accepted and valuable
  • Python is feasible if APOPHIS enters through a spec-based testing layer, not by immediately building deep framework hooks everywhere

4.3 Go

  • kin-openapi: mature OpenAPI parsing and request/response validation primitives
  • oapi-codegen: server/client generation and middleware integration around OpenAPI
  • Huma: Go framework centered on OpenAPI and JSON Schema

What this validates:

  • Go has strong OpenAPI infrastructure already
  • APOPHIS should not try to replace that infrastructure
  • a Go expansion should differentiate on behavioral contracts, generative testing, and diagnostics rather than basic schema validation

5. Feasibility Ranking

5.1 Express

Feasibility: high

Why:

  • same language and runtime
  • same property-based tooling can be reused
  • same outbound mocking and deterministic machinery can mostly stay in Node
  • same CLI can target Express services without much product change

Main work:

  • route discovery strategy
  • spec acquisition strategy
  • middleware-phase mapping for observe mode
  • local test execution path if no inject() equivalent is standardized

Recommendation:

  • make Express the first non-Fastify adapter

5.2 Python

Feasibility: medium, but only with narrower scope

Why:

  • strong OpenAPI ecosystem already exists
  • property-based testing from schema has prior art
  • FastAPI and Connexion are good initial targets because they are already spec-first or OpenAPI-native

Constraints:

  • current APOPHIS engine is Node-shaped
  • runtime hooks and lifecycle assumptions do not transfer directly
  • full feature parity would likely require a native implementation or a language-neutral service protocol

Recommendation:

  • enter Python through CLI/spec mode first
  • consider a native adapter only after proving demand in one framework such as FastAPI

5.3 Go

Feasibility: medium-low in the near term

Why:

  • the OpenAPI ecosystem is mature
  • the framework ecosystem is more fragmented in behavior and metadata patterns
  • typed codegen and middleware are already strong in Go, so APOPHIS has to bring something more specific than validation

Constraints:

  • current JS/Node runtime assumptions do not transfer cleanly
  • property-based and stateful testing experience would need careful native design
  • deep native adapter work is much closer to a new product than a thin port

Recommendation:

  • defer native Go work until a framework-neutral route manifest and CLI/test protocol are stable

6. The Architecture Split Required

This expansion is only realistic if APOPHIS is explicitly split into:

6.1 Core

Framework-neutral pieces:

  • APOSTL parser/evaluator
  • contract extraction/inference
  • route/operation model
  • request generation rules
  • runners for verify and qualify
  • result shaping, deduplication, replay artifacts
  • chaos and qualification logic

6.2 Adapter layer

Framework-specific pieces:

  • route discovery
  • spec acquisition
  • in-process request execution or test client integration
  • runtime observe integration
  • cleanup behavior

6.3 CLI and remote execution layer

A language-neutral layer that can:

  • load OpenAPI documents
  • select operations and routes
  • generate requests from schema
  • hit a live server or a framework-specific test adapter
  • evaluate APOPHIS behavioral contracts on observed responses

This layer is the bridge to Python and Go without requiring a full immediate reimplementation.

7. The Minimal Adapter Contract

To support more than Fastify, APOPHIS needs a small explicit host contract.

Conceptually, an adapter should provide:

interface ApophisAdapter {
  listRoutes(): RouteManifest[]
  execute(request: ExecutableRequest): Promise<EvalContext>
  getSpec?(): Record<string, unknown>
  installObserveMode?(opts: ObserveOptions): Promise<void> | void
  cleanup?(): Promise<void>
}

And for cross-language operation, a language-neutral manifest should exist:

interface RouteManifest {
  method: string
  path: string
  schema?: Record<string, unknown>
  annotations?: {
    requires?: string[]
    ensures?: string[]
    category?: string
    timeout?: number
  }
}

Without this seam, “support another framework” means spreading Fastify assumptions into more code.

8. The Best Near-Term Product Strategy

The best expansion strategy is not “port the Fastify plugin everywhere.”

It is:

  1. keep Fastify as the deepest adapter
  2. make the CLI/spec mode the main portability wedge
  3. use adapters only where the ergonomics justify it

This aligns with prior art like Dredd and Schemathesis and avoids competing directly with full spec-first frameworks.

9. Proposed Roadmap

Phase 0: Internal Core Extraction

Goal:

  • make the adapter boundary explicit without changing outward behavior yet

Work:

  • rename Fastify-shaped interfaces to neutral names
  • define a route manifest model
  • define an execution adapter contract
  • move route discovery behind an adapter boundary
  • build adapter conformance tests

Exit criteria:

  • current Fastify implementation passes through the new adapter seam
  • runners no longer need direct Fastify concepts in their public types

Phase 1: CLI Spec Mode

Goal:

  • support verify and selected qualify workflows against any running HTTP server using OpenAPI plus APOPHIS extensions

Scope:

  • input: OpenAPI document URL or file
  • target: base URL of running service
  • output: APOPHIS verify report, replay artifacts, seeds

Supports initially:

  • verify
  • variants
  • selected qualify modes like scenario and protocol flows

Does not support initially:

  • native runtime observe middleware
  • in-process cleanup hooks
  • full framework lifecycle integration

Why this phase matters:

  • it gives immediate value to Express, Python, and Go without deep adapter work
  • it measures cross-language demand before native adapter investment

Exit criteria:

  • APOPHIS can run useful spec-driven checks against a live OpenAPI-described service from the CLI alone

Phase 2: Express Adapter

Goal:

  • deliver the first non-Fastify in-process integration in the same language runtime

Scope:

  • Express route discovery via registered manifest or explicit spec file
  • local verify path
  • limited observe middleware path if safe

Design note:

  • Express may require explicit spec or explicit route manifest rather than introspecting route-local schemas the way Fastify does

Exit criteria:

  • one real Express sample app can run verify
  • documentation supports the first successful verify setup as directly as the Fastify guide

Phase 3: Python CLI-First Support

Goal:

  • support Python services without a native Python APOPHIS runtime yet

Scope:

  • documented FastAPI and Connexion integration through spec mode
  • optional hooks or fixtures for auth/test data setup
  • replayable verify runs in CI

Exit criteria:

  • one reference FastAPI app passes APOPHIS CLI-driven verification
  • the product story is useful without native middleware or runtime hooking

Phase 4: Go CLI-First Support

Goal:

  • support Go services via spec mode and existing OpenAPI middleware ecosystem

Scope:

  • reference integrations with kin-openapi or oapi-codegen based services
  • verify-focused first
  • qualify later only for flows with identified adoption demand and reproducible CI value

Exit criteria:

  • one reference Go service passes CLI-driven verification

Phase 5: Decide Whether Native Python or Go Adapters Are Worth It

This should be a market and adoption decision, not an assumption.

Only proceed if:

  • CLI/spec mode is proving useful in those ecosystems
  • users want runtime observe or deeper in-process integration
  • APOPHIS can differentiate from ecosystem-native validators and codegen tools

10. What Not To Do

Do not:

  • promise feature parity across Fastify, Express, Python, and Go immediately
  • try to own request validation stacks that each ecosystem already solved well
  • tie multi-language expansion to full runtime hooks on day one
  • port Fastify-specific docs language directly into other ecosystems
  • assume route-local annotation ergonomics exist outside Fastify without explicit manifests

The feasible product boundary is:

  • APOPHIS as a behavioral contract engine and qualification CLI for OpenAPI-described services
  • APOPHIS adapters where implementation cost is low and CI value is clear

The infeasible near-term boundary is:

  • APOPHIS as a fully native, feature-parity runtime plugin across all major JS, Python, and Go frameworks

12. Recommendation

Current recommendation:

  1. do not pursue multi-language expansion now
  2. keep APOPHIS focused on Node and Fastify
  3. continue with CLI, docs, first-signal flow, and verify / observe / qualify simplification first
  4. revisit Express only if a cheap adapter seam emerges after the Fastify redesign stabilizes

Deferred roadmap, if revisited later:

  1. extract core and adapter seam
  2. build CLI/spec mode
  3. ship Express next
  4. validate demand through Python and Go via CLI first
  5. only then decide whether native adapters are worth it

Anything broader should be treated as a major platform strategy, not a routine extension of the current Fastify product.