The Laravel Integration Bridge
The integration bridge is the only part of Geni that touches Laravel runtime components. Its responsibilities are intentionally narrow — discover routes and serve the documentation portal — so that the analysis engine beneath it stays completely isolated from the framework.- Route discovery reads the Laravel route collection to extract registered route URIs, HTTP methods, route names, and middleware assignments. It produces a list of plain route descriptors that are handed down to the analysis engine, with no framework types attached.
- Service registration wires up all console commands (
geni:export,geni:check,geni:analyze,geni:cache,geni:clear,geni:mcp,geni:mcp:serve) and the HTTP routes that power the documentation portal (GET /docs/api,GET /docs/api.json,GET /docs/api/mcp,POST /docs/api/mcp). - Documentation portal renders the interactive UI that wraps the generated OpenAPI specification and handles configured authentication.
The Framework-Free Analysis Engine
The analysis engine is strictly framework-free. It receives route descriptors and source file paths, and returns a complete OpenAPI document — no Laravel classes involved at any stage.- It never imports Laravel framework classes, which means it cannot accidentally trigger framework behavior, resolve service container bindings, or produce side effects during analysis.
- It parses PHP source files into Abstract Syntax Trees, extracting all information about controllers, Form Requests, Eloquent resources, and migration files by inspecting the AST nodes directly.
- Because it has no framework dependency, the engine can run in complete isolation — no application bootstrapping, no database, no
.envfile required.
Schema Discovery Pipeline
When you rungeni:export, Geni executes the following seven steps in sequence. Each step feeds its output directly into the next, building up a progressively richer representation of your API until the final OpenAPI document is ready.
1
Migration Replay
Geni parses all migration files in timestamp order, tracking table creations, column definitions, column alterations, foreign key declarations, and dropped columns into an in-memory schema. This schema becomes the authoritative source of column type information for every subsequent step.
2
Route Discovery
Geni reads the Laravel route collection and filters registered routes by API prefix (e.g.
api/) or a custom resolver closure defined in your config/geni.php. Each matching route is recorded with its URI, HTTP methods, controller class, and action method name.3
Source File Parsing
For each discovered route, Geni locates the controller source file, parses it into an AST, and isolates the target action method. It also captures the file’s namespace and import declarations so that all subsequent steps can resolve fully-qualified class names.
4
Parameter Inference
Geni matches URI route parameters (e.g.
{user}) against model route keys and the columns in the replayed migration schema. Query parameters are extracted from request accessor calls or Spatie QueryBuilder allowedFilters() / allowedSorts() definitions found in the AST.5
Request Body Inference
Geni inspects Form Request
rules() methods, inline $request->validate() calls in controllers, and Spatie Data DTO property declarations. The extracted rules are converted to a JSON Schema object for the OpenAPI requestBody.6
Response Inference
Geni walks each controller action’s return statements and return type hints. It resolves
JsonResource classes, response()->json() arrays, Data::from() Spatie Data objects, and bare Eloquent model returns into typed 200, 201, or 204 response schemas using the migration schema for column type information.7
Annotation Merging
Geni scans each controller method for explicit override annotations — such as
#[Response], #[QueryParameter], #[BodyParameter], and #[PathParameter] — and merges them over the data inferred in the previous steps. Annotations always win, giving you a reliable escape hatch when static inference needs a nudge.