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

Someline Starter Laravel Package

someline/someline-starter

Someline Starter is a Laravel-based application boilerplate for rapid web development. It ships with RESTful API support, user authentication, role and permission management, and a modular structure, giving you a solid foundation to build modern PHP apps faster.

View on GitHub
Deep Wiki
Context7

Getting Started

Someline Starter is an application skeleton, not a library you composer require into an existing Laravel app. The fastest path is to clone it, fill in .env, and run the installer/seed commands listed in the README of the tag you're on (older releases ship a someline:* artisan command; if yours doesn't, the manual path is key:generate → jwt:secret → migrate → db:seed).

git clone https://github.com/someline/someline-starter.git my-api
cd my-api && composer install
cp .env.example .env
php artisan key:generate
php artisan jwt:secret          # tymon/jwt-auth signs your API tokens
# set DB_*, APP_URL, API_* in .env
php artisan migrate --seed

Look at these five places first, in this order:

  1. .env + config/api.php — API prefix, version, and debug flags decide every URL you'll call.
  2. app/Http/Controllers/Api/V1/ — the existing AuthController, UserController, and RoleController are your reference implementations.
  3. app/Repositories/ — where query logic lives; BaseRepository subclasses are auto-resolved.
  4. app/Transformers/V1/ — Fractal transformers that shape every JSON response.
  5. The route files under app/Http/Routes — versioned, so a new endpoint means a new route entry, not a controller change.

First use case: authenticate and read yourself back. POST {prefix}/{version}/auth/login with email/password returns a JWT; then GET .../auth/me with Authorization: Bearer <token> proves the guard, middleware, repository, and transformer chain all work end to end before you write a line of your own code.

Implementation Patterns

The canonical request flow is Controller → Repository → Transformer → Responder. Keep it that way; the value of this starter is that every resource looks identical.

class PostController extends ApiController
{
    public function __construct(PostRepository $repository)
    {
        $this->repository = $repository;
    }

    public function index(Request $request)
    {
        $posts = $this->repository
            ->with(['author'])                       // eager load for transformers
            ->pushCriteria(new PostFilterCriteria($request))
            ->paginate($request->get('per_page', 15));

        return $this->respondWithPagination($posts, new PostTransformer);
    }

    public function show($id)
    {
        return $this->respondWithItem(
            $this->repository->find($id),
            new PostTransformer
        );
    }
}

Repository conventions. BaseRepository gives you model(), presenter()/transformer(), create, update, delete, findByField, paginate, with, scopeQuery. Reusable filters belong in app/Repositories/Criteria — implement apply($model, $repository) and pushCriteria() them; that's the idiomatic way to keep index endpoints from turning into request-parsing soup.

Transformers, not raw models. Every model returned to a client goes through app/Transformers/V1/*. Use $availableIncludes / $defaultIncludes with includeAuthor() methods for relationship expansion (?include=author,comments), and always eager-load the matching relations in the repository — Fractal will happily fire N+1 queries otherwise.

Auth and RBAC. JWT via tymon/jwt-auth, auth:api guard. Login issues JWTAuth::fromUser($user); logout invalidates the token; me returns Auth::user(). Roles/permissions hang off the User model (hasRole, can) and are enforced with route middleware — put the check on the route, not in the controller body, so it's visible in the route file.

Validation. Form Requests in app/Http/Requests extending the API-aware base request, so failures render as JSON 422 through the same responder envelope instead of redirecting. Never $request->validate() inline in an API controller if you want consistent error shapes.

Versioning. New breaking work means app/Http/Controllers/Api/V2, app/Transformers/V2, and a new route file — copy, don't branch inside V1 classes. This is cheap here and the single biggest reason to keep the structure intact.

Testing. Feature tests hitting the versioned URL with a token are the highest-value tests: $token = JWTAuth::fromUser(factory(User::class)->create()) then $this->getJson($url, ['Authorization' => "Bearer $token"]). Assert on the envelope (data.*), not on the full payload — transformers change often.

Gotchas and Tips

  • This is a 2020-era stack. The last tagged release is mid-2020 and the external dependent count is effectively zero, which is normal for a skeleton but means you own all upgrades. Pin PHP and Laravel versions early; budget for a framework upgrade before you budget for features.
  • composer create-project vs clone. Because it's a full app, require-ing it into another Laravel project will fight over config/, routes, and the App namespace. Start clean or copy the Repositories/Transformers/responder wiring by hand.
  • jwt:secret is mandatory. A missing JWT_SECRET produces confusing "token could not be parsed" errors that look like auth bugs. Also configure a real cache store (Redis) — token blacklisting on logout misbehaves on some cache drivers/expired TTLs.
  • Prefix/version drift. Changing config/api.php version breaks every existing client and every hardcoded test URL at once. Read it from config in tests, not string literals.
  • Debug mode leaks internals. The API debug/config flag controls whether stack traces appear in JSON error responses. Ensure it's off in production; also exclude the API prefix from debugbar so it doesn't inject markup into responses.
  • Presenter vs Transformer naming. Older README sections and blog posts say "presenters"; current code uses Fractal transformers. If a doc snippet doesn't match, trust app/Transformers and the installed someline/* package source over the prose.
  • Responder envelope assumptions. respondWithItem expects a single model and respondWithCollection/respondWithPagination expect collections — mixing them throws inside Fractal with a vague message. Check config/api.php (or the responder config) for the exact data/error shape before writing SDKs or frontend parsers against it.
  • Seeded users. The default seeder creates an admin with a known password. Rotate it before the first deploy and before exposing anything publicly.
  • Stale config/route caches. After adding route files or pushCriteria config, php artisan route:clear && php artisan config:clear. Avoid closures in config arrays if you intend to config:cache.
  • Extension points worth knowing: a new Criteria class for filtering, a new transformer include* method for relations, a repository interface bound in the app's repository service provider for swapping implementations, and overriding the responder's error format to match your organisation's error contract. Those four cover most day-to-day customisation without touching the framework wiring.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings