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

Halapi Laravel Package

bigz/halapi

HAL JSON representation helper for HATEOAS APIs. Uses annotations and conventions to expose entities with links/relations, with pluggable URL generator, annotation reader, object manager, and pagination. Symfony-friendly today; aiming for framework-agnostic/PSR.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bigz/halapi
    

    Add to config/app.php under providers:

    Bigz\Halapi\HalapiServiceProvider::class,
    
  2. Basic Usage Define a HAL resource in a controller or service:

    use Bigz\Halapi\Resource;
    
    class UserController extends Controller
    {
        public function show($id)
        {
            $user = User::findOrFail($id);
            return Resource::make('users', $user)
                ->add('self', route('users.show', $user))
                ->add('posts', route('users.posts', $user));
        }
    }
    
  3. First Use Case Return a HAL-formatted API response with embedded links and relationships:

    return Resource::collection('users', User::all())
        ->add('self', route('users.index'))
        ->add('create', route('users.store'));
    

Implementation Patterns

Resource Creation

  • Single Resource

    Resource::make('resource-name', $model)
        ->add('link-name', '/url')
        ->embed('related', $relatedResource);
    
  • Collections

    Resource::collection('resource-name', $collection)
        ->add('self', route('resource.index'))
        ->paginate(10); // Optional pagination
    

Embedding Related Resources

$user = User::with('posts')->find(1);
return Resource::make('users', $user)
    ->embed('posts', $user->posts);

Customizing HAL Structure

  • Override Defaults

    Resource::make('users', $user)
        ->setEmbeddedKey('_embedded'); // Default is '_embedded'
        ->setLinksKey('_links');       // Default is '_links'
    
  • Dynamic Link Generation

    $resource->add('self', function ($user) {
        return route('users.show', $user);
    });
    

API Versioning

// In routes/api.php
Route::prefix('v1')->group(function () {
    Route::get('/users/{id}', [UserController::class, 'show']);
});

Integration with Laravel Features

  • API Resources Combine with Laravel's JsonResource for hybrid responses:

    return Resource::make('users', UserResource::make($user));
    
  • Form Requests Validate HAL-specific fields (e.g., _links):

    public function rules()
    {
        return [
            '_links.self' => 'required|url',
        ];
    }
    

Gotchas and Tips

Common Pitfalls

  • Circular References Avoid embedding deeply nested resources to prevent infinite loops:

    // Bad: $user->posts->comments->user...
    // Good: Limit depth or use `->without('comments')`.
    
  • Link Validation Ensure all _links are absolute URLs or valid relative paths. HALAPI does not validate them by default.

  • Pagination Quirks Paginated collections require explicit ->paginate():

    // Missing pagination will return all items
    Resource::collection('users', User::paginate(10));
    

Debugging

  • Inspect Raw Output Use dd($resource->toArray()) to debug structure before returning.

  • Check for Missing Keys If _links or _embedded are missing, verify:

    $resource->hasLinks(); // Returns bool
    $resource->hasEmbedded(); // Returns bool
    

Extension Points

  • Custom Embedders Override Bigz\Halapi\Embedder to modify embedding logic:

    class CustomEmbedder extends Embedder
    {
        public function embed($resource, $key, $value)
        {
            // Custom logic
            return parent::embed($resource, $key, $value);
        }
    }
    
  • Middleware for HAL Responses Add middleware to enforce HAL format:

    namespace App\Http\Middleware;
    
    class EnforceHalFormat
    {
        public function handle($request, Closure $next)
        {
            $response = $next($request);
            if ($response->isJson() && !Halapi::isHal($response->getData())) {
                abort(406, 'HAL format required');
            }
            return $response;
        }
    }
    

Configuration Quirks

  • No Built-in Caching Manually cache responses if needed:

    return Cache::remember("hal_{$id}", now()->addHours(1), function () use ($user) {
        return Resource::make('users', $user);
    });
    
  • Deprecated Methods Avoid Resource::item() (use Resource::make() instead) and Resource::items() (use Resource::collection()).

Performance Tips

  • Lazy Embedding Use ->embedWhen() to conditionally embed:

    $resource->embedWhen($user->hasPosts(), 'posts', $user->posts);
    
  • Minimize Embedded Data Select only necessary fields:

    $resource->embed('posts', $user->posts->load('title'));
    
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.
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
sandermuller/package-boost-php
sandermuller/boost-core
depa/sulu-google-reviews-bundle
croct/plug-symfony
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle