composer require raml-org/raml-php-parser
use Raml\Parser;
$parser = new Parser();
$apiDefinition = $parser->parse('path/to/api.raml');
$title = $apiDefinition->getTitle();
$version = $apiDefinition->getVersion();
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, [...]))
}
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);
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;
});
}
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);
}
$routes = $apiDefinition->getResourcesAsUri(new SymfonyRouteFormatter());
// Integrate with Laravel's route cache or a custom docs generator
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());
}
});
}
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'));
});
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()]);
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');
}
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'));
});
RAML 1.0 Incomplete Support:
Archived Package Risks:
Performance Overhead:
Cache::forever('raml.api.definition', $apiDefinition);
Symfony Route Formatter Dependency:
SymfonyRouteFormatter requires Symfony’s Routing component. If you’re not using Symfony, this may add unnecessary dependencies.NoRouteFormatter for basic route extraction or implement a custom formatter.Schema Validation Quirks:
$validator = new Validator($schema);
$validator->setThrowExceptions(false); // Disable exceptions for custom error handling
$errors = $validator->validate($data);
Resource URI Conflicts:
uriParameters and queryParameters can clash with Laravel’s routing. Sanitize URIs before registration:
$sanitizedUri = str_replace(['{', '}'], '', $uri);
Enable Parser Debugging: Set the parser to verbose mode to diagnose parsing issues:
$parser = new Parser();
$parser->setDebug(true); // Logs parsing steps
Validate RAML Syntax: Use online RAML validators (e.g., RAML Validator) before parsing in PHP.
Inspect Parsed Objects:
Dump the parsed ApiDefinition to understand its structure:
dd($apiDefinition->getResources());
Handle Deprecated PHP Features:
If using PHP 8.x, suppress deprecation warnings for implode() with historical parameter order:
error_reporting(E_ALL & ~E_DEPRECATED);
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()),
];
}
}
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
];
}
}
RAML 1.0 Feature Gaps: If you need missing RAML 1.0 features (e.g., libraries), consider:
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);
Case Sensitivity: RAML is case-sensitive. Ensure your file
How can I help you explore Laravel packages today?