Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Raml Php Parser Laravel Package

raml-org/raml-php-parser

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install via Composer:
    composer require raml-org/raml-php-parser
    
  2. Parse a RAML file:
    use Raml\Parser;
    
    $parser = new Parser();
    $apiDefinition = $parser->parse('path/to/api.raml');
    
  3. Access basic metadata:
    $title = $apiDefinition->getTitle();
    $version = $apiDefinition->getVersion();
    

First Use Case: Route Extraction

Extract routes from a RAML file to generate Laravel route definitions:

$routes = $apiDefinition->getResourcesAsUri();
foreach ($routes as $method => $uri) {
    // Generate Laravel route logic (e.g., Route::get($uri, [...]))
}

First Use Case: Schema Validation

Validate a request body against a RAML-defined schema:

$schemaParser = new \Raml\Schema\JsonSchemaParser();
$schema = $schemaParser->parse($apiDefinition->getSchemas()['User']);
$validator = new \Raml\Validator\Validator($schema);
$isValid = $validator->validate($requestData);

Implementation Patterns

Workflow: API Contract Validation in Laravel

  1. Parse RAML in a Service Provider:
    public function boot()
    {
        $ramlParser = new Parser();
        $apiDefinition = $ramlParser->parse(storage_path('api.raml'));
    
        // Cache parsed definition for performance
        app()->singleton('raml.api', function () use ($apiDefinition) {
            return $apiDefinition;
        });
    }
    
  2. Middleware for Request Validation:
    public function handle($request, Closure $next)
    {
        $apiDefinition = app('raml.api');
        $resource = $apiDefinition->getResourceForUri($request->path());
    
        if ($resource && $resource->hasBody()) {
            $schema = $resource->getBody()->getSchema();
            $validator = new Validator($schema);
            if (!$validator->validate($request->all())) {
                abort(400, 'Invalid request body');
            }
        }
    
        return $next($request);
    }
    
  3. Generate API Documentation:
    $routes = $apiDefinition->getResourcesAsUri(new SymfonyRouteFormatter());
    // Integrate with Laravel's route cache or a custom docs generator
    

Workflow: Dynamic Route Registration

Use SymfonyRouteFormatter to register routes dynamically:

$routeFormatter = new SymfonyRouteFormatter();
$routes = $apiDefinition->getResourcesAsUri($routeFormatter);
$routeCollection = $routeFormatter->getRouteCollection();

// Register routes in Laravel
foreach ($routeCollection->getResources() as $resource) {
    Route::group([
        'prefix' => $resource->getPrefix(),
    ], function () use ($resource) {
        foreach ($resource->getMethods() as $method => $route) {
            Route::{$method}($route->getPath(), $route->getController());
        }
    });
}

Integration Tips

  1. Caching Parsed Definitions: Cache the parsed ApiDefinition to avoid reprocessing RAML files on every request:

    $apiDefinition = Cache::remember('raml.api.definition', now()->addHours(1), function () {
        return (new Parser())->parse(storage_path('api.raml'));
    });
    
  2. Custom Schema Parsers: Extend functionality by implementing SchemaParserInterface:

    class CustomSchemaParser implements SchemaParserInterface
    {
        public function parse(array $schemaDefinition): SchemaDefinitionInterface
        {
            // Custom logic to parse schemas
            return new CustomSchemaDefinition($schemaDefinition);
        }
    }
    

    Pass it to the Parser constructor:

    $parser = new Parser([new CustomSchemaParser()]);
    
  3. Error Handling: Wrap parsing in try-catch blocks to handle malformed RAML:

    try {
        $apiDefinition = $parser->parse($ramlFile);
    } catch (\Raml\Exception\ParseException $e) {
        Log::error("RAML parsing failed: " . $e->getMessage());
        abort(500, 'Invalid API specification');
    }
    
  4. Laravel Service Provider Integration: Bind the parser and API definition to the container:

    $this->app->singleton(Parser::class, function () {
        return new Parser();
    });
    
    $this->app->bind('raml.api', function ($app) {
        return $app->make(Parser::class)->parse(storage_path('api.raml'));
    });
    

Gotchas and Tips

Pitfalls

  1. RAML 1.0 Incomplete Support:

    • Missing Features: Libraries, user-defined facets, overlays, and annotations are not implemented. Avoid using these in RAML specs.
    • Workaround: Stick to RAML 0.8 or use a subset of RAML 1.0 features (e.g., type expressions, enums).
  2. Archived Package Risks:

    • No New Releases: Last update was in 2022. Potential issues with:
      • PHP 8.x compatibility (test locally before use).
      • Laravel 10+ compatibility (some Symfony components may be outdated).
    • Workaround: Fork the repository and maintain it internally if critical.
  3. Performance Overhead:

    • Parsing large RAML files can be slow. Cache the parsed definition aggressively:
      Cache::forever('raml.api.definition', $apiDefinition);
      
  4. Symfony Route Formatter Dependency:

    • The SymfonyRouteFormatter requires Symfony’s Routing component. If you’re not using Symfony, this may add unnecessary dependencies.
    • Workaround: Use NoRouteFormatter for basic route extraction or implement a custom formatter.
  5. Schema Validation Quirks:

    • The validator may throw cryptic errors for complex schemas. Enable detailed error reporting:
      $validator = new Validator($schema);
      $validator->setThrowExceptions(false); // Disable exceptions for custom error handling
      $errors = $validator->validate($data);
      
  6. Resource URI Conflicts:

    • RAML’s uriParameters and queryParameters can clash with Laravel’s routing. Sanitize URIs before registration:
      $sanitizedUri = str_replace(['{', '}'], '', $uri);
      

Debugging Tips

  1. Enable Parser Debugging: Set the parser to verbose mode to diagnose parsing issues:

    $parser = new Parser();
    $parser->setDebug(true); // Logs parsing steps
    
  2. Validate RAML Syntax: Use online RAML validators (e.g., RAML Validator) before parsing in PHP.

  3. Inspect Parsed Objects: Dump the parsed ApiDefinition to understand its structure:

    dd($apiDefinition->getResources());
    
  4. Handle Deprecated PHP Features: If using PHP 8.x, suppress deprecation warnings for implode() with historical parameter order:

    error_reporting(E_ALL & ~E_DEPRECATED);
    

Extension Points

  1. Custom Route Formatters: Implement RouteFormatterInterface to generate Laravel-specific routes:

    class LaravelRouteFormatter implements RouteFormatterInterface
    {
        public function formatResource($resource)
        {
            // Generate Laravel route definitions
            return [
                'method' => $resource->getMethod(),
                'uri' => $resource->getUri(),
                'controller' => 'ApiController@' . snake_case($resource->getMethod()),
            ];
        }
    }
    
  2. Schema Validation Extensions: Extend Validator to integrate with Laravel’s validation system:

    class LaravelValidator extends Validator
    {
        public function getLaravelRules()
        {
            // Convert RAML schema to Laravel validation rules
            return [
                'required' => $this->schema->isRequired(),
                'type' => $this->schema->getType(),
                // Add custom rules
            ];
        }
    }
    
  3. RAML 1.0 Feature Gaps: If you need missing RAML 1.0 features (e.g., libraries), consider:

    • Preprocessing RAML: Use a tool like RAML to OpenAPI converters to bridge gaps.
    • Custom Parsers: Implement partial support for missing features by extending the parser classes.

Configuration Quirks

  1. Parser Constructor Options: The Parser constructor accepts an array of SchemaParserInterface instances. Ensure your custom parsers are registered:

    $schemaParsers = [
        new JsonSchemaParser(),
        new XmlSchemaParser(),
        new CustomSchemaParser(),
    ];
    $parser = new Parser($schemaParsers);
    
  2. Case Sensitivity: RAML is case-sensitive. Ensure your file

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor