Search by

mk990 / mkapi

mk990

JSON:API scaffolding with Scramble docs and JWT auth for Laravel

Package info

github.com/mk990/mkapi

pkg:composer/mk990/mkapi

Statistics

Installs: 621

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

v0.2.1 2026-09-28 13:51 UTC

This package is auto-updated.

Last update: 2026-09-28 13:51:45 UTC


README

GitHub stars

GitHub license

MkApi Logo

๐Ÿš€ API Development with Laravel MkApi

MkApi is a Laravel 13 CLI tool that scaffolds a JSON:API with JWT authentication. It reads your migrations and generates JSON:API resources, form requests, controllers and routes, and Scramble turns that code into OpenAPI documentation. No annotations required. ๐Ÿงฐโœจ

Requires Laravel 13+. Earlier MkApi releases (v0.1.x) used l5-swagger; mkapi:init migrates such projects automatically (see Upgrading from Swagger).

๐Ÿ“ฆ Packages Used

This project utilizes the following packages to boost development and maintain high standards:

๐Ÿ“ฆ Package Name ๐Ÿ“ Description ๐Ÿ”ข Version
scramble OpenAPI documentation generated from your code, no annotations needed. ^0.13
jwt-auth JSON Web Token (JWT) authentication for secure APIs. ^2.7
larastan Static analysis tool to catch bugs early using PHPStan for Laravel. ^3.0
laravel-backup Seamless backup of databases and files in Laravel apps. ^9.1
laravel-pulse Real-time performance insights for Laravel applications. ^1.4
laravel-telescope Debugging assistant for Laravel. Monitors requests, logs, queries, mail, jobs, and more. ^5.8
laravel-persian-validation Persian-specific validation rules for form requests. ^2.0
verta Date handling between Solar and Gregorian calendars. ^8.5
turnstile Easy integration with Cloudflare Turnstile for bot protection. ^2.0

โš™๏ธ Installation

๐Ÿ“ฅ Install MkApi Tool

composer require mk990/mkapi --dev
php artisan mkapi:init

๐Ÿ”ง The following packages are installed by default:

  • scramble
  • jwt-auth
  • larastan

๐Ÿ“š API docs are served at /docs/api (the OpenAPI JSON at /docs/api.json). They are public by default; to restrict them, add Dedoc\Scramble\Http\Middleware\RestrictedDocsAccess::class back to middleware in config/scramble.php.

The installer also:

  • publishes app/Exceptions/JsonApiExceptionRenderer.php and registers it in bootstrap/app.php, so every error under /api is a JSON:API error document
  • makes unauthenticated API requests return 401 instead of redirecting to a login route
  • publishes an AuthController (register, login, refresh, me, password reset, email verification) and a UserResource

๐ŸŽ›๏ธ Install Optional Packages

Use the interactive install command to choose additional tools:

php artisan mkapi:init --package

๐Ÿ“Œ Available packages:

  • laravel-backup
  • laravel-pulse
  • laravel-telescope
  • laravel-persian-validation
  • verta
  • turnstile

๐Ÿ› ๏ธ Usage

MkApi runs your migrations against a temporary database on your default MySQL/MariaDB connection and reads each table's columns. Every command takes a table or model name (post, Post, BlogPost, blog_posts) or all.

๐Ÿงฑ Generate a model

php artisan mkapi:model post
php artisan mkapi:model all

Writes app/Models/Post.php with $fillable (every column but keys and timestamps) and casts() derived from the column types.

๐ŸŽฎ Generate a controller

php artisan mkapi:controller post
php artisan mkapi:controller post --code
php artisan mkapi:controller all --code

Without --code you get app/Http/Controllers/PostController.php with empty index / store / show / update / destroy methods to fill in yourself. With --code MkApi writes the CRUD code and the classes it uses:

File Contents
app/Http/Resources/PostResource.php JsonApiResource exposing every column except id, password, remember_token, deleted_at
app/Http/Requests/StorePostRequest.php Validation rules derived from the column types, nullability and defaults
app/Http/Requests/UpdatePostRequest.php The same rules, each field optional (sometimes)
app/Http/Controllers/PostController.php index / store / show / update / destroy using route model binding

Either way Route::apiResource('posts', PostController::class); is added to routes/api.php.

๐Ÿง  The generated controller:

public function store(StorePostRequest $request): JsonResponse
{
    $post = Post::create($request->validated())->refresh();

    return (new PostResource($post))->response()->setStatusCode(201);
}

public function show(Post $post): PostResource
{
    return new PostResource($post);
}

Scramble documents it from those types alone: the request body from StorePostRequest, the response from PostResource, and 401/404/422 from the middleware and bindings.

๐Ÿงฉ Options

Option Commands Effect
--force mkapi:model, mkapi:controller Overwrite existing files
--code mkapi:controller Generate the CRUD code, resource and form requests instead of an empty controller
--public mkapi:controller Do not put the controller behind the auth middleware

๐Ÿ“„ Response format

Everything under /api speaks JSON:API with Content-Type: application/vnd.api+json. Request bodies are plain JSON objects.

// GET /api/posts/1
{ "data": { "id": "1", "type": "posts", "attributes": { "title": "Hello", "status": "draft" } } }

// POST /api/auth/login
{ "meta": { "access_token": "eyJโ€ฆ", "token_type": "bearer", "expires_in": 604800 } }

// 422
{ "errors": [{ "status": "422", "title": "Validation Error", "detail": "The title field is required.", "source": { "pointer": "/title" } }] }

Lists are paginated with ?page= and ?per_page= (max 100) and support sparse fieldsets (?fields[posts]=title) and includes (?include=author) for relationships declared in the resource's $relationships.

In your own controllers, return resources directly or use the base controller helpers:

  • $this->success($data): a resource or a model (as a JSON:API resource), a paginator/collection of models (as a JSON:API collection), anything else as a meta document
  • $this->meta(['message' => 'โ€ฆ']): a meta-only document
  • $this->error('message', status: 403): a JSON:API error document

โฌ†๏ธ Upgrading from Swagger

Running php artisan mkapi:init in a project set up by an older MkApi:

  • strips every #[OA\โ€ฆ] attribute, @OA\โ€ฆ docblock and use OpenApi\โ€ฆ import from app/
  • deletes config/l5-swagger.php, resources/views/vendor/l5-swagger and storage/api-docs
  • removes the L5_SWAGGER_* lines from .env and .env.example
  • runs composer remove darkaonline/l5-swagger
  • replaces the base Controller with the JSON:API one (success() and error() keep their signatures)

The old mkapi:modelSWG and mkapi:controllerSWG commands are gone; use mkapi:model and mkapi:controller --code. Existing controllers keep working, but return JSON:API documents through the new success()/error().

๐Ÿงช Testing

composer test          # everything
composer test-unit     # generator and stripping logic only, no Laravel app
composer test-coverage # HTML report in coverage/ (needs Xdebug)

The feature tests install MkApi into a throwaway Laravel 13 skeleton with Testbench and a fake composer binary (no network needed). They then send real HTTP requests to the generated API: auth, CRUD, validation and error documents, middlewares, and the Scramble output.

Reading the schema needs MySQL or MariaDB. Without a server those tests are skipped; to run them, point them at a user allowed to create databases:

docker run -d --rm --name mkapi-db -e MARIADB_ROOT_PASSWORD=secret -p 127.0.0.1:3307:3306 mariadb:lts
MKAPI_TEST_MYSQL_HOST=127.0.0.1 MKAPI_TEST_MYSQL_PORT=3307 MKAPI_TEST_MYSQL_PASSWORD=secret composer test

๐Ÿค Contributing

We love contributions! If you have ideas or improvements, feel free to:

๐Ÿ“ License

This project is licensed under the MIT License.

๐Ÿ‘ฅ Contributors