Skip to content

Remove redundant /api/ prefix from route definitions #168

@kevalyq

Description

@kevalyq

Issue Description

Remove redundant /api/ prefix from Laravel route definitions to align with production API URL structure. Currently, internal routing uses /api/v1/* but production API is accessible at https://api.secpal.app/v1/* (no /api/ in URL).

Type: Technical Debt / Refactoring
Justification: We're at v0.x.x - breaking changes allowed!

Current State vs Desired State

Current (Inconsistent):

// routes/api.php
Route::prefix('v1')->group(function () {
    Route::get('/users', ...);
});

// .env / Laravel routing
// Internal: /api/v1/users
// Production URL: https://api.secpal.app/v1/users  ← No /api/ prefix!

Desired (Consistent):

// routes/api.php
Route::prefix('v1')->group(function () {
    Route::get('/users', ...);
});

// No prefix needed - access directly at /v1/*
// Production URL: https://api.secpal.app/v1/users  ✅ Matches routing

Why This Matters

  1. Documentation Confusion:

  2. Test Confusion:

    • Tests use $this->getJson('/api/v1/users') but production uses /v1/users
    • Developers need to remember the discrepancy
  3. Cognitive Load:

    • Internal routing vs external URL mismatch
    • "Why do we have /api/ in routes but not in URLs?"

Proposed Solution

Option 1: Remove /api/ Prefix Entirely (Recommended)

Changes:

  1. Remove 'prefix' => 'api' from bootstrap/app.php or routes/api.php
  2. Update all tests: /api/v1/*/v1/*
  3. Update any hardcoded URLs in code

Pros:

  • ✅ Direct match: Route = URL
  • ✅ Simpler to understand
  • ✅ No mental mapping needed

Cons:

  • ⚠️ Breaking change (but we're v0.x.x!)
  • ⚠️ Need to update all tests

Option 2: Keep /api/ but Document Why (Not Recommended)

Changes:

  1. Add comment in routes explaining discrepancy
  2. Update .github/copilot-instructions.md to document this

Pros:

  • ✅ No breaking changes

Cons:

  • ❌ Continues confusion
  • ❌ Future PRs will repeat same mistake
  • ❌ Doesn't solve root cause

Affected Files

Code Changes (~10 files):

  • routes/api.php - Remove or update prefix
  • bootstrap/app.php - Check for api prefix configuration
  • All test files (~20 files) - Update URLs

Documentation (Already Fixed in PR #162):

  • README.md
  • CHANGELOG.md
  • docs/api/rbac-endpoints.md
  • docs/guides/role-management.md
  • docs/guides/permission-system.md
  • docs/guides/temporal-roles.md
  • docs/guides/direct-permissions.md
  • docs/rbac-architecture.md
  • docs/GUARD_ARCHITECTURE.md

Implementation Plan

Phase 1: Preparation

  • Audit all route definitions in routes/api.php
  • Audit all test files for /api/v1/ usage
  • Create list of all affected files

Phase 2: Remove Prefix

  • Remove 'prefix' => 'api' from route configuration
  • Test locally with DDEV

Phase 3: Update Tests

  • Bulk replace /api/v1//v1/ in all test files
  • Run full test suite to verify
  • Fix any remaining hardcoded URLs

Phase 4: Verification

  • All 277+ tests passing
  • PHPStan Level Max clean
  • Laravel Pint clean
  • Preflight checks pass

Breaking Changes

⚠️ BREAKING CHANGE - But Acceptable (v0.x.x):

Before:

# Internal Laravel routing
POST /api/v1/users/123/roles

# But production URL was always:
POST https://api.secpal.app/v1/users/123/roles

After:

# Internal Laravel routing matches production
POST /v1/users/123/roles

# Production URL unchanged:
POST https://api.secpal.app/v1/users/123/roles

Impact:

Alternatives Considered

Alternative 1: Add /api/ to Production URL

Rejected: Subdomain api.secpal.app already indicates it's an API. Adding /api/ prefix is redundant.

Alternative 2: Use Nginx Rewrite

Rejected: Adds complexity. Better to fix at Laravel level.

Alternative 3: Keep Current State

Rejected: Causes ongoing confusion and documentation drift.

Success Criteria

Effort Estimate

Size: Small (2-4 hours)

  • 30 min: Remove prefix configuration
  • 1 hour: Bulk update tests
  • 30 min: Run tests and fix issues
  • 1 hour: Review and verification

Milestone

🎯 v0.3.0 - Technical debt cleanup

Labels

  • type: refactor 🔨
  • priority: low 🟢
  • area: routing 🛣️
  • effort: S (2-4 hours)
  • breaking-change ⚠️ (acceptable in v0.x)

Related Issues/PRs


Note: This is a "nice-to-have" cleanup, not urgent. Can be tackled during a maintenance sprint or when working on routing-related features.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions