Skip to content

url-rewriting#10

Merged
ljonesfl merged 2 commits intodevelopfrom
feature/url-rewriting
Jan 12, 2026
Merged

url-rewriting#10
ljonesfl merged 2 commits intodevelopfrom
feature/url-rewriting

Conversation

@ljonesfl
Copy link
Member

@ljonesfl ljonesfl commented Jan 12, 2026

Note

Separates routing concerns and enables URL rewrites plus named routes.

  • New config/routing.yaml support: Application::loadRoutingConfig() reads rewrites and controller_paths; falls back to neuron.yaml if absent, with routing.yaml taking precedence
  • Named routes plumbing: Application::addRoute() now accepts $name and passes it to router get/post/put/delete; registerAttributeRoute() forwards attribute name directly
  • Route scanning behavior: loadAttributeRoutes() reads controller paths from Registry (set by routing.yaml) with backward-compatible fallback, and respects empty arrays
  • Docs/examples: README adds routing.yaml section and examples; example neuron.yaml notes routing config location
  • Tests: tests/Mvc/MockRouter updated to accept $name in get/post

Written by Cursor Bugbot for commit 69def15. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Dedicated routing.yaml support for URL rewrites and controller path configuration; routing.yaml takes precedence over neuron.yaml.
    • Named-route support for improved route identification and management.
  • Documentation

    • Added documentation and examples for the new routing configuration and migration notes.
  • Tests

    • Updated test harness to support named routes during testing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Adds a dedicated routing configuration loader that reads rewrites and controller_paths from routing.yaml (falling back to neuron.yaml). Application route APIs accept an optional route name and attribute-based route loading uses the configured controller paths via the Registry.

Changes

Cohort / File(s) Summary
Configuration Example
examples/config/neuron.yaml
Adds a Routing block with controller_paths listing Controllers under the Mvc namespace.
Documentation
readme.md
Adds documentation for routing.yaml including sample rewrites and controller_paths; notes precedence of routing.yaml over neuron.yaml and removes routes_path: config from main example.
Core Routing Logic
src/Mvc/Application.php
Adds protected function loadRoutingConfig(): void; updates addRoute() signature to accept ?string $name = null; loadRoutes() now calls loadRoutingConfig(); loadAttributeRoutes() prefers controller_paths from Registry and falls back to neuron.yaml; parses routing.yaml rewrites into Router and logs diagnostics.
Tests / Mocks
tests/Mvc/MockRouter.php
Extends get() and post() signatures to accept optional ?string $name = null and forwards the name to parent calls to support named routes in tests.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Config as Config Loader
    participant Router as Router
    participant Registry as Registry
    participant AttrScanner as Attribute Scanner

    App->>Config: loadRoutingConfig()
    Config->>Config: Check for routing.yaml
    alt routing.yaml exists
        Config->>Config: Parse YAML (rewrites, controller_paths)
        Config->>Router: Register rewrites
        Config->>Registry: Store controller_paths
    else
        Config->>Config: Log fallback to neuron.yaml
        Config->>Registry: Load controller_paths from neuron.yaml
    end

    App->>AttrScanner: loadAttributeRoutes()
    AttrScanner->>Registry: Get controller_paths
    AttrScanner->>AttrScanner: Scan controller paths and extract attributes
    AttrScanner->>App: addRoute(method, route, controllerMethod, request, filters, name)
    App->>Router: Register route (with optional name)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I hopped through YAML, neat and bright,
Placed paths and rewrites just right,
Names on routes I now can keep,
Registry stores them while I leap,
A joyful bunny routing night!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'url-rewriting' is vague and generic, referring to only one aspect of the changeset without clearly summarizing the main change. Consider a more descriptive title like 'Add dedicated routing configuration with named routes support' that better captures the primary additions.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 61.53846% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Mvc/Application.php 61.53% 15 Missing ⚠️
Flag Coverage Δ Complexity Δ
mvc 64.56% <61.53%> (-0.10%) 1731.00 <14.00> (+9.00) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ Complexity Δ
src/Mvc/Application.php 63.94% <61.53%> (-1.69%) 76.00 <14.00> (+9.00) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Mvc/Application.php (2)

135-146: DocBlock is missing the @param for the new $name parameter.

The method signature now includes ?string $name = null, but the PHPDoc block doesn't document this parameter. Add the missing parameter documentation for completeness.

📝 Suggested documentation update
 	/**
 	 * @param string $method
 	 * @param string $route
 	 * @param string $controllerMethod
 	 * @param string $request
 	 * @param string|array $filters
+	 * @param string|null $name Optional route name for named routes
 	 * @return \Neuron\Routing\RouteMap
 	 *
 	 * @throws BadRequestMethod
 	 * @throws Exception
 	 */

496-518: Consider adding a type check for the parsed YAML result.

Yaml::parse() can return null for empty files or a scalar value for non-mapping YAML content. While isset() handles null gracefully, adding an explicit array type check improves defensive coding.

🛡️ Suggested defensive check
 		try
 		{
 			$config = \Symfony\Component\Yaml\Yaml::parse( $content );
+
+			if( !is_array( $config ) )
+			{
+				Log::warning( "routing.yaml does not contain a valid configuration array" );
+				return;
+			}

 			// Configure URL rewrites
 			if( isset( $config['rewrites'] ) && is_array( $config['rewrites'] ) )
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 949790f and 69def15.

📒 Files selected for processing (1)
  • src/Mvc/Application.php
🧰 Additional context used
🧬 Code graph analysis (1)
src/Mvc/Application.php (1)
tests/Mvc/MockRouter.php (1)
  • get (21-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (4)
src/Mvc/Application.php (4)

150-206: LGTM!

The $name parameter is consistently passed to all router methods (PUT, GET, POST, DELETE), and the switch statement properly handles all request method types with UNKNOWN throwing a BadRequestMethod exception.


458-462: LGTM!

The ordering is correct—loadRoutingConfig() is called before loadAttributeRoutes() to ensure controller paths are available in the Registry before route scanning begins.


528-550: LGTM!

The fallback logic is well-structured: Registry (from routing.yaml) is checked first, then neuron.yaml for backward compatibility. The distinction between null (not configured) and empty array (explicitly disabled) is correctly handled with === null.


593-603: LGTM!

Passing $def->name directly to addRoute() is cleaner than setting it afterward on the RouteMap. This enables the router to handle named routes and duplicate detection during registration.

catch( \Symfony\Component\Yaml\Exception\ParseException $e )
{
Log::error( "Failed to parse routing.yaml: " . $e->getMessage() );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registry value persists across Application instances

Medium Severity

The loadRoutingConfig() method only sets Routing.ControllerPaths in the singleton Registry when routing.yaml exists and contains controller_paths. When the file doesn't exist or parsing fails, the Registry key is never cleared. In loadAttributeRoutes(), the code checks Registry::getInstance()->get('Routing.ControllerPaths') and only falls back to neuron.yaml when the value is null. If a previous Application instance set this Registry key, subsequent instances without routing.yaml will use the stale configuration instead of falling back to their own neuron.yaml settings. This affects test isolation and scenarios with multiple Application instances.

Additional Locations (1)

Fix in Cursor Fix in Web

@ljonesfl ljonesfl merged commit 69def15 into develop Jan 12, 2026
3 of 4 checks passed
@ljonesfl ljonesfl deleted the feature/url-rewriting branch January 12, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant