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

Slim Rest Base Laravel Package

awurth/slim-rest-base

A REST API boilerplate for the Slim PHP microframework, giving you a ready-made base structure with routing, authentication, validation, error handling, and database integration so you can skip setup and start building endpoints fast.

View on GitHub
Deep Wiki
Context7

Getting Started

slim-rest-base is a project skeleton, not a library — you don't composer require it, you clone or create-project it and then own the code. That distinction drives everything about how you use it day-to-day.

composer create-project awurth/slim-rest-base my-api
# or
git clone https://github.com/awurth/slim-rest-base my-api && cd my-api && composer install

First places to look, in order:

  1. composer.json — pins the Slim major version (this skeleton is Slim 3-era) and lists the actually-interesting pieces: PHP-DI, Doctrine ORM/Migrations, Monolog, and awurth's own validation/token-auth packages. Read this before anything else; it tells you whether you're on PHP 7.x-only constraints.
  2. public/index.php — the front controller. This is where the app, container, middleware stack, and error handler are wired. Every request flows through here.
  3. Config directory (app/ or config/) — settings for DB, Doctrine, Monolog, and environment-specific overrides.
  4. Routes and controllers — the src/ tree shows the intended convention: controllers grouped by resource, DI-resolved, returning PSR-7 responses.

First use case: get one resource end-to-end. Create a Doctrine entity, generate a migration, add a thin controller action that loads a repository and returns JSON, register a route for it, and curl it. That exercises the whole stack — container, ORM, routing, middleware — in one pass and surfaces config problems immediately.

Implementation Patterns

Thin controllers, fat services. The skeleton's value is the wiring, so keep the wiring clean. Controllers should take PSR-7 Request/Response, pull a service from the container (constructor injection via PHP-DI autowiring usually just works), and return a response. Push business logic into services or repositories so controllers stay testable.

Routing per resource. Group routes by resource with a prefix and attach middleware at the group level rather than per-route:

$app->group('/api/v1/users', function () {
    $this->get('', UserController::class . ':index');
    $this->post('', UserController::class . ':store');
    $this->get('/{id:[0-9]+}', UserController::class . ':show');
})->add($container->get(AuthMiddleware::class));

The regex constraint on {id} is worth adopting everywhere — it prevents route collisions and gives you clean 404s instead of type errors deep in a repository.

Doctrine as the data layer. Entities in the conventional src/Entity namespace, mapping via annotations/XML as the skeleton configures it, and schema changes exclusively through migrations. Inject EntityManager (or a repository) rather than reaching for a global. Keep the proxy/cache directories writable and out of version control.

JSON in, JSON out. Use the request's parsed body for input and a small response helper (or json_encode into a withBody stream) for output. Standardize an error envelope — {"error": {"code": ..., "message": ..., "details": ...}} — in the custom error handler so clients get consistent shapes for 400/404/422/500. The skeleton ships an error handler; adapt it rather than replacing Slim's default blindly.

Validation at the boundary. awurth's validation integrates naturally with the container: validate the parsed body in the controller or a form-request-style middleware, and short-circuit with a 422 before touching Doctrine. This keeps entities free of validation concerns.

Middleware for cross-cutting work. Auth (token/JWT), CORS, content negotiation, and request logging all belong in the middleware stack registered in public/index.php. Order matters — auth should typically run after body parsing but before routing-dependent logic.

Config per environment. Keep secrets in environment variables, not committed config files. The skeleton's settings array is the seam; layer environment overrides rather than branching on APP_ENV inside application code.

Gotchas and Tips

It's archived, and that's the headline. Slim 3 is end-of-life, and the dependency tree (Doctrine, Monolog, PSR-7 implementations) will have drifted. Treat composer update with suspicion — run it in a branch, read the diff, and be prepared to pin. Check composer audit before starting. If you're greenfielding today, consider this skeleton as a reference architecture to crib from while building on Slim 4, rather than a foundation to build on directly.

You own all the code, including its bugs. Because it's a skeleton, there's no upstream to pull fixes from — no composer update will improve the application layer. Budget time for the first upgrade pass and don't expect the repo to help.

PSR-7 immutability bites everyone once. $response->withStatus(201) returns a new object; forgetting the assignment silently drops your status code. Same for headers. Linters won't catch it.

getParsedBody() returns null unless the request has the right Content-Type. If clients forget application/json, you'll get mysterious nulls rather than errors. Validate the content type explicitly or add body-parsing middleware.

Container compilation and route caching are the two biggest production wins, but both invalidate on config changes. Wire them into your deploy script, not ad hoc — otherwise a stale cache will send you debugging phantom 404s.

Error handler transparency. In development, let exceptions bubble with stack traces. In production, log the full exception through Monolog and return only the sanitized envelope. A handler that swallows exceptions in both environments is the most common reason people can't debug this kind of skeleton.

Doctrine proxies and dev mode. Regenerate proxies after entity changes, and make sure the proxy directory is writable by the web user. Permission errors here masquerade as "class not found" and waste hours.

Testing needs a separate database. Point the test environment at its own schema and wrap each test in a transaction rolled back in tearDown — otherwise tests mutate dev data and become order-dependent. The skeleton's container makes it easy to swap the EntityManager for a test-configured one.

Extension points worth knowing: DI definitions (override any service without touching core code), custom middleware (the cleanest place for new cross-cutting behavior), Doctrine event subscribers (audit logging, timestamps), and the console entry point for custom CLI commands alongside the Doctrine migration commands.

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.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json