spatie/laravel-resource-links
Abandoned package that adds action URLs to Laravel API resources. Generate per-item and collection links (show/edit/update/delete, index/create/store) from a controller or defined actions, so resources include ready-to-use endpoints without manual URL building.
Installation:
composer require spatie/laravel-resource-links
Publish the config (if needed):
php artisan vendor:publish --provider="Spatie\ResourceLinks\ResourceLinksServiceProvider"
Basic Usage:
Extend your JsonResource with the HasLinks trait:
use Spatie\ResourceLinks\HasLinks;
class UserResource extends JsonResource
{
use HasLinks;
}
First Use Case:
Define a links() method in your resource to specify which links to include:
public function links()
{
return [
'self' => 'index',
'show' => 'show',
'create' => 'create',
'edit' => 'edit',
];
}
The package will automatically resolve URLs based on your controller actions.
Default Controller Mapping:
The package assumes standard RESTful controller methods (index, show, store, update, destroy). If your controller follows this pattern, no additional configuration is needed.
Custom Controller Actions:
For non-standard action names (e.g., customAction), explicitly define them in the links() method:
public function links()
{
return [
'custom' => 'customAction',
];
}
Dynamic Link Generation: Use closures to dynamically generate links based on the resource:
public function links()
{
return [
'self' => fn() => route('users.show', $this->resource),
'delete' => fn() => route('users.destroy', $this->resource),
];
}
Global Defaults:
Override defaults in config/resource-links.php:
'default_links' => [
'self' => 'index',
'show' => 'show',
],
Conditional Links: Use closures to conditionally include links:
public function links()
{
return [
'edit' => fn() => auth()->check() ? 'edit' : null,
];
}
Nested Resource Links:
For nested resources (e.g., PostResource with comments link), use route parameters:
public function links()
{
return [
'comments' => 'posts.comments.index',
];
}
Embedding Links in JSON:API:
Combine with HasMeta for a complete API response:
use Spatie\ResourceLinks\HasLinks;
use Spatie\ResourceLinks\HasMeta;
class UserResource extends JsonResource
{
use HasLinks, HasMeta;
}
Customizing Link Labels:
Override the linkLabels() method to change link names in the response:
protected function linkLabels(): array
{
return [
'self' => 'user_self',
'edit' => 'edit_profile',
];
}
Controller Not Found: If the package can't resolve a route, ensure:
routes/api.php or routes/web.php.'show' maps to show() in the controller).Circular Dependencies:
Avoid circular references when dynamically generating links (e.g., self linking to show which links back to self). Use null or omit problematic links.
Cached Routes: Clear route cache if links stop working:
php artisan route:clear
Inspect Generated Links: Temporarily dump the resolved links in your resource:
public function links()
{
$links = $this->getLinks();
dd($links); // Debug resolved URLs
return $links;
}
Check Route Existence: Verify routes exist with:
php artisan route:list
Middleware Issues:
If links fail silently, ensure your API routes are protected by the correct middleware (e.g., api or auth:api).
Custom Link Resolvers:
Extend the Spatie\ResourceLinks\LinkResolver class to handle custom logic:
class CustomLinkResolver extends LinkResolver
{
public function resolve($action, $resource)
{
// Custom resolution logic
}
}
Bind it in AppServiceProvider:
ResourceLinks::resolver(new CustomLinkResolver());
Override Default Behavior:
Replace the HasLinks trait entirely by publishing and modifying the trait:
php artisan vendor:publish --tag=resource-links-traits
Localization:
Localize link labels by overriding linkLabels() and using Laravel's translation system:
protected function linkLabels(): array
{
return [
'self' => __('resource_links.self'),
];
}
Avoid Over-Fetching:
Only include necessary links in the links() method to reduce payload size.
Lazy Loading: For large datasets, consider lazy-loading links via a separate endpoint or query parameter.
Fork and Maintain: Fork the repository to apply fixes or updates if critical issues arise.
Alternative Packages: Consider modern alternatives like:
spatie/laravel-hal (for HAL+JSON).darkaonline/l5-swagger (for API documentation with links).route() helper directly in resources.How can I help you explore Laravel packages today?