Weave 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

Service Basics Extension Laravel Package

gustavosantarosa/service-basics-extension

A lightweight Laravel extension for service-basics that adds reusable service-layer scaffolding, helping you organize business logic into clean, testable service classes with minimal boilerplate. A simple starting point for consistent service patterns in projects already using the base package.

View on GitHub
Deep Wiki
Context7

Getting Started

This package gives you an opinionated base Service + Controller layer for Eloquent resources: a BaseService for query/business logic and a controller base that wires up index/show (and soft-delete handling via a "Trash" trait). Version 2.1.0 is mostly an internal reorganization into traits, so the fastest way to get productive is to read the traits rather than the base classes.

  1. Install:

    composer require quantum-tecnology/service-basics-extension
    

    Confirm the exact Composer name on Packagist/the repo README — the GitHub name (Quantum-Tecnology/Service-Basics-Extension) is not always the package name.

  2. Look first at:

    • src/Traits/ — this is where the real behavior now lives (Search, Sort, Scopes, Trash, and the renamed filter/include trait).
    • BaseService — now a thin shell that composes those traits.
    • The base controller's index/show — also abstracted into traits in 2.1.0.
  3. Publish any config (if the package ships one) and skim it for searchable/sortable/include whitelists:

    php artisan vendor:publish --provider="QuantumTecnology\ServiceBasicsExtension\ServiceBasicsServiceProvider"
    
  4. First use case — a read-only listing endpoint:

    class UserService extends BaseService
    {
        protected string $model = User::class;
        protected array $searchable = ['name', 'email'];
        protected array $sortable   = ['name', 'created_at'];
        protected array $allowedIncludes = ['posts', 'roles'];
    }
    
    class UserController extends BaseController
    {
        public function __construct(UserService $service)
        {
            $this->service = $service;
        }
    }
    

    Then hit GET /users?search=ana&sort=-created_at&include=roles. That request-driven behavior is the package's main selling point and the thing to verify first in your app.

Implementation Patterns

Service-per-resource, controller delegates. Keep controllers nearly empty. Put validation-adjacent filters and query shaping in the service; the base controller's index/show traits will call into it. Override index/show only when you need a different response shape:

public function index(Request $request)
{
    $paginator = $this->service->index($request);
    return UserResource::collection($paginator);
}

Request-driven listing. The new Scopes trait is designed to apply search/sort/filter automatically from the request. Treat this as the default listing pipeline, and layer your own scopes alongside it:

// In your model
public function scopeActive($query): void
{
    $query->where('active', true);
}
// In the service, combine automatic + explicit
$this->service->index($request)->through(fn ($u) => ...);

Compose traits explicitly for custom flows. Because 2.1.0 split logic into traits, you can now use only what you need — e.g. a "report" service that sorts but never exposes includes:

class ReportService extends BaseService
{
    use Search, Sort; // deliberately not Trash / FilterInclude
}

Soft deletes via the Trash trait. Model the expected REST surface: DELETE /users/{id} (soft), GET /users/trash or ?trashed=1 (listing), PATCH /users/{id}/restore, DELETE /users/{id}/force. Verify the exact route/query convention your version exposes — the changelog only says the trait was extracted, not that the surface changed.

Includes / eager loading. Use the renamed filter/include trait for ?include=posts,roles with an allow-list on the service. This is the right place to prevent arbitrary relationship loading.

Testing. Feature-test the query-string contract — search, sort direction, pagination, includes, trash — because most of 2.1.0 is a refactor and you want a regression net before you upgrade.

Gotchas and Tips

  • 2.1.0 is a refactor release — assume breakage in subclasses. Base service methods moved into traits, and the filter/include trait was renamed. If you extended BaseService and overrode methods, or referenced the old trait name directly, grep for it and update. Run composer dump-autoload and your test suite immediately after upgrading.

  • Trait method collisions. With Search, Sort, Scopes and Trash all in play, identical method names are plausible. Resolve explicitly:

    use Search, Sort {
        Search::apply insteadof Sort;
        Sort::apply as applySort;
    }
    

    If you see "trait method has not been applied" or a method silently resolving to the wrong trait, this is why.

  • Auto-scopes are an injection surface. Request-driven sorting that maps directly to orderBy($request->sort) allows ordering by non-indexed or sensitive columns. Always configure a sortable whitelist and reject unknown keys; same for searchable columns and includes.

  • include without a whitelist is an N+1 machine. Even with an allow-list, eager-load counts can explode on large pages. Cap page size and consider withCount for counts instead of loading relations.

  • phpCSFixer was added in 2.1.0. It affects the package's own source, not your application code. Don't run the package's fixer config against your app/ directory — it will reformat your codebase and produce a noisy diff.

  • Debugging the index pipeline. When a listing returns unexpected results, isolate the stage: log the query before/after search, then sort, then scopes, then includes (->toSql() at each point). The trait split makes this easier than the old monolithic service — use it.

  • Extension points to prefer: model scopes for reusable constraints, service properties for whitelists, resource classes for output shape. Avoid overriding the base index/show unless you need a structurally different response; the base traits are the intended seam.

  • Upgrade check: diff 2.0.5 → 2.1.0 and look specifically for renamed traits/methods. The changelog flags the rename but not a deprecation alias, so anything still referencing the old trait name will fail at class-load time.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums