Bytedocs for Laravel provides seamless integration with your Laravel application, including K6 performance testing - a feature unique to the Laravel implementation.
Install via Composer:
composer require idnexacloud/laravel-bytedocs
Run the install command to auto-setup everything:
php artisan bytedocs:install
This will:
Publish config file to config/bytedocs.php Publish assets (CSS/JS) to public/bytedocs/ Add all ByteDocs environment variables to your .env That's it! Visit http://localhost:8000/docs and your documentation is ready.
The package auto-registers and works out of the box with zero configuration. Just install and visit /docs.
Want to customize? Add to your .env:
BYTEDOCS_TITLE="My Laravel API"
BYTEDOCS_VERSION="1.0.0"
BYTEDOCS_DESCRIPTION="My awesome Laravel API"
Or publish the config for advanced customization:
php artisan vendor:publish --provider= "ByteDocs\Laravel\ByteDocsServiceProvider" --tag= "bytedocs-config"
Bytedocs automatically detects:
// routes/api.php
Route :: get ( '/users/{id}' , [ UserController ::class , 'show' ]);
Route :: post ( '/users' , [ UserController ::class , 'store' ]);
Route :: put ( '/users/{id}' , [ UserController ::class , 'update' ]);
Route :: delete ( '/users/{id}' , [ UserController ::class , 'destroy' ]);
All routes are automatically discovered and documented.
class StoreUserRequest extends FormRequest
{
public function rules ()
{
return [
'name' => 'required|string|max:255' ,
'email' => 'required|email|unique:users' ,
'age' => 'required|integer|min:0|max:150' ,
];
}
}
class UserController extends Controller
{
public function store ( StoreUserRequest $request)
{
// Bytedocs automatically documents:
// - All fields from rules()
// - Required/optional status
// - Validation rules (min, max, email, etc.)
// - Types (string, integer, email, etc.)
}
}
class User extends Model
{
protected $fillable = [ 'name' , 'email' , 'age' ];
protected $hidden = [ 'password' ];
protected $casts = [
'email_verified_at' => 'datetime' ,
'age' => 'integer' ,
];
}
class UserController extends Controller
{
public function show ($id)
{
return User :: find ($id);
// Bytedocs automatically detects User model structure
}
}
class UserResource extends JsonResource
{
public function toArray ($request)
{
return [
'id' => $this -> id,
'name' => $this -> name,
'email' => $this -> email,
'created_at' => $this -> created_at -> toDateTimeString (),
];
}
}
class UserController extends Controller
{
public function index ()
{
return UserResource :: collection ( User :: all ());
// Automatically documented with correct schema
}
}
Edit config/bytedocs.php:
return [
'title' => env ( 'BYTEDOCS_TITLE' , 'API Documentation' ),
'version' => env ( 'BYTEDOCS_VERSION' , '1.0.0' ),
'description' => env ( 'BYTEDOCS_DESCRIPTION' , '' ),
'docs_path' => env ( 'BYTEDOCS_DOCS_PATH' , '/docs' ),
'auto_detect' => env ( 'BYTEDOCS_AUTO_DETECT' , true ),
];
'base_urls' => [
[
'name' => 'Production' ,
'url' => env ( 'BYTEDOCS_PRODUCTION_URL' , 'https://api.example.com' ),
],
[
'name' => 'Staging' ,
'url' => env ( 'BYTEDOCS_STAGING_URL' , 'https://staging.example.com' ),
],
[
'name' => 'Local' ,
'url' => env ( 'BYTEDOCS_LOCAL_URL' , 'http://localhost:8000' ),
],
],
'auth' => [
'enabled' => env ( 'BYTEDOCS_AUTH_ENABLED' , false ),
'type' => env ( 'BYTEDOCS_AUTH_TYPE' , 'session' ), // session, basic, api_key
'username' => env ( 'BYTEDOCS_AUTH_USERNAME' , 'admin' ),
'password' => env ( 'BYTEDOCS_AUTH_PASSWORD' , 'secret' ),
'session_expire' => env ( 'BYTEDOCS_AUTH_SESSION_EXPIRE' , 1440 ), // minutes
],
'exclude_paths' => [
'_ignition' ,
'telescope' ,
'horizon' ,
'sanctum/csrf-cookie' ,
'api/health' ,
],
Laravel is the only implementation with built-in K6 integration!
Install K6:
# macOS
brew install k6
# Linux
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
# Windows
choco install k6
Via UI : Navigate to any endpoint in /docsClick "Performance Test" buttonConfigure test parameters :
Virtual Users (VUs) Duration Ramp-up stages Run and view results
'k6' => [
'enabled' => env ( 'BYTEDOCS_K6_ENABLED' , true ),
'path' => env ( 'BYTEDOCS_K6_PATH' , null ), // Auto-detect if null
'default_vus' => env ( 'BYTEDOCS_K6_DEFAULT_VUS' , 10 ),
'default_duration' => env ( 'BYTEDOCS_K6_DEFAULT_DURATION' , '30s' ),
],
// Generated by Bytedocs
import http from 'k6/http' ;
import { sleep, check } from 'k6' ;
export const options = {
vus: 10 ,
duration: '30s' ,
stages: [
{ duration: '10s' , target: 10 },
{ duration: '10s' , target: 20 },
{ duration: '10s' , target: 0 },
],
};
export default function () {
const res = http. get ( 'http://localhost:8000/api/users' );
check (res, {
'status is 200' : ( r ) => r.status === 200 ,
'response time < 500ms' : ( r ) => r.timings.duration < 500 ,
});
sleep ( 1 );
}
After test execution, you'll see:
Total Requests : Number of requests madeFailure Rate : Percentage of failed requestsAvg Response Time : Average response durationMax VUs : Peak virtual usersData Transferred : Total data sent/receivedDuration Percentiles : P95, P99 response times
php artisan bytedocs:generate
Generates fresh documentation JSON file.
php artisan bytedocs:clear
Clears documentation cache.
php artisan bytedocs:routes
Lists all detected routes.
class StorePostRequest extends FormRequest
{
public function rules ()
{
return [
'title' => 'required|string|max:255' ,
'content' => 'required|string' ,
'published_at' => 'nullable|date' ,
'tags' => 'array' ,
'tags.*' => 'string' ,
];
}
public function messages ()
{
return [
'title.required' => 'Post title is required' ,
'content.required' => 'Post content cannot be empty' ,
];
}
}
class PostResource extends JsonResource
{
public function toArray ($request)
{
return [
'id' => $this -> id,
'title' => $this -> title,
'slug' => $this -> slug,
'content' => $this -> content,
'author' => new UserResource ( $this -> whenLoaded ( 'author' )),
'tags' => TagResource :: collection ( $this -> whenLoaded ( 'tags' )),
'published_at' => $this -> published_at ?-> toDateTimeString (),
'created_at' => $this -> created_at -> toDateTimeString (),
];
}
}
class UserController extends Controller
{
/**
* Get all users
*
* Returns a paginated list of all users in the system.
*
* @response UserResource[]
*/
public function index ()
{
return UserResource :: collection ( User :: paginate ());
}
/**
* Create a new user
*
* Creates a new user account with the provided information.
*
* @param StoreUserRequest $request
* @response 201 UserResource
*/
public function store ( StoreUserRequest $request)
{
$user = User :: create ($request -> validated ());
return new UserResource ($user);
}
}
Route :: prefix ( 'api/v1' ) -> group ( function () {
Route :: middleware ( 'auth:sanctum' ) -> group ( function () {
Route :: apiResource ( 'users' , UserController ::class );
Route :: apiResource ( 'posts' , PostController ::class );
});
});
// app/Http/Middleware/ByteDocsAuth.php
class ByteDocsAuth
{
public function handle ($request, Closure $next)
{
if ($request -> is ( 'docs*' )) {
// Custom authentication logic
if ( ! $this -> isAuthorized ($request)) {
abort ( 403 );
}
}
return $next($request);
}
}
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\ByteDocsAuth ::class ,
],
];
Clear route cache : php artisan route:clearClear config cache : php artisan config:clearRegenerate docs : php artisan bytedocs:generateVerify installation : k6 versionSpecify path in config : 'k6' => ['path' => '/usr/local/bin/k6']Check PATH : Ensure k6 is in system PATHCache documentation : Set 'cache' => true in configExclude unnecessary routes : Add to exclude_pathsDisable auto-detect in production : Set 'auto_detect' => false