markdown
---
name: generators-backend
description: Use when the user asks about LaraJS backend code generation, generated API structure, Laravel file architecture (controllers, services, repositories, resources, models, migrations, factories, seeders, routes, tests), language/i18n generation, or how the backend generator produces PHP code. Also use when asking about adding languages to the generator or running API documentation with Scribe.
---
# API Structure (Monorepo)
LaraJS generates the API according to the following structure:
```txt
.
├── apps
│ ├── api
│ │ ├── app
│ │ │ ├── Http
│ │ │ │ ├── Controllers
│ │ │ │ │ ├── Api
│ │ │ │ │ │ └── V1
│ │ │ │ │ │ └── CategoryController.php
│ │ │ │ ├── Requests
│ │ │ │ │ └── V1
│ │ │ │ │ └── StoreCategoryRequest.php
│ │ │ │ └── Resources
│ │ │ │ └── V1
│ │ │ │ └── CategoryResource.php
│ │ │ ├── Models
│ │ │ │ └── Category.php
│ │ │ ├── Repositories
│ │ │ │ └── Category
│ │ │ │ ├── CategoryRepository.php
│ │ │ │ └── CategoryRepositoryInterface.php
│ │ │ └── Services
│ │ │ └── V1
│ │ │ └── Category
│ │ │ └── CategoryService.php
│ │ ├── database
│ │ │ ├── factories
│ │ │ │ └── CategoryFactory.php
│ │ │ ├── migrations
│ │ │ │ └── 2024_10_03_023029_create_categories_table.php
│ │ │ └── seeders
│ │ │ └── CategorySeeder.php
│ │ ├── lang
│ │ │ ├── en
│ │ │ │ ├── route.php
│ │ │ │ └── table.php
│ │ │ ├── ja
│ │ │ │ ├── route.php
│ │ │ │ └── table.php
│ │ │ └── vi
│ │ │ ├── route.php
│ │ │ └── table.php
│ │ ├── routes
│ │ │ └── api-v1.php
│ │ └── tests
│ │ └── Feature
│ │ └── CategoryTest.php
│ ├── cms
│ └── frontend
├── packages
└── ...
```
## Form Request
The form request validates data before performing any actions in the controller.
```php
<?php
namespace App\Http\Requests\V1;
class StoreCategoryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
// validation
];
}
}
```
## Controller
The controller handles API requests for resource management.
```php
<?php
namespace App\Http\Controllers\Api\V1;
class CategoryController extends Controller implements HasMiddleware
{
public function __construct(private readonly CategoryService $categoryService) {}
public static function middleware(): array
{
// Middleware instance is used to enforce specific permissions on different actions
}
public function index(Request $request): JsonResponse
{
// Find all
}
public function store(StoreCategoryRequest $request): JsonResponse
{
// Create
}
public function show(int $id, Request $request): JsonResponse
{
// Find One
}
public function update(int $id, StoreCategoryRequest $request): JsonResponse
{
// Update
}
public function destroy(int $id): JsonResponse
{
// Delete
}
}
```
## Service
The service layer handles the business logic.
```php
<?php
namespace App\Services\V1\Category;
readonly class CategoryService
{
/**
* @param CategoryRepositoryInterface<Category> $categoryRepository
*/
public function __construct(private CategoryRepositoryInterface $categoryRepository) {}
public function findAll(Request $request): LengthAwarePaginator|CursorPaginator|Paginator|Collection
{
// Find All
}
public function create(array $data): Category
{
// Create
}
public function find(int $id, Request $request): Category
{
// Find One
}
public function update(int $id, array $data): Category
{
// Update
}
public function delete(int $id): bool
{
// Delete
}
}
```
## Repository
**CategoryRepository.php**
```php
<?php
namespace App\Repositories\Category;
/**
* @template T of Category
*
* @implements CategoryRepositoryInterface<T>
*
* @extends BaseRepository<T>
*/
class CategoryRepository extends BaseRepository implements CategoryRepositoryInterface
{
public function getModel(): string
{
return Category::class;
}
}
```
**CategoryRepositoryInterface.php**
```php
<?php
namespace App\Repositories\Category;
/**
* @template T
*
* @extends BaseRepositoryInterface<T>
*/
interface CategoryRepositoryInterface extends BaseRepositoryInterface {}
```
## API Documentation
LaraJS leverages [Laravel Scribe](https://scribe.knuckles.wtf/laravel/) to automatically generate API documentation.
```php
php artisan scribe:generate
```
Access docs at `{url}/docs`.
## Eloquent Resource
Resources transform model data into JSON for API responses.
```php
<?php
namespace App\Http\Resources\V1;
class CategoryResource extends JsonResource
{
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}
```
## Model
```php
<?php
namespace App\Models;
class Category extends Model
{
use HasFactory;
use UserSignature; // Checked `User Signature`
use SoftDeletes; // Checked `Soft Deletes`
protected $table = 'categories';
protected $fillable = [
// columns in table
];
}
```
## Database
### Factory
```php
<?php
namespace Database\Factories;
class CategoryFactory extends Factory
{
protected $model = Category::class;
public function definition(): array
{
return [
// faker
];
}
}
```
### Migration
```php
<?php
return new class extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements("id");
// columns
});
}
public function down()
{
Schema::dropIfExists('categories');
}
};
```
### Seed
```php
<?php
namespace Database\Seeders;
class CategorySeeder extends Seeder
{
public function run(): void
{
Category::factory()->count(10)->create();
}
}
```
## Language
**route.php**
```php
<?php
return [
...
// START - category
'category' => 'Category Sidebar',
'category_overview' => 'List Category Sidebar',
'category_create' => 'Create Category Sidebar',
'category_edit' => 'Edit Category Sidebar',
];
```
**table.php**
```php
<?php
return [
...
// START - category
'category' => [
'id' => 'ID',
...
]
];
```
## Language Generator
By default, LaraJS generates language configurations for en (English), ja (Japanese), and vi (Vietnamese). To add more languages:
1. Publish the `generator.php` configuration file:
```php
php artisan vendor:publish --tag=larajs-core-config
```
2. Add new language entries in the `lang` array:
```php
return [
'lang' => [
'en' => [
'route' => '', // Define localized route names for English
'table' => '', // Define table labels for English
],
'ja' => [
'route' => '',
'table' => '',
],
'vi' => [
'route' => '',
'table' => '',
],
// Add additional languages here
],
]
```
**Generate I18n**
```php
// Synchronize i18n language settings for the frontend.
php artisan larajs:i18n
// packages/common/src/lang/vue-i18n-locales.generated.json
```
## Route
**api-v1.php**
```php
<?php
Route::group(['middleware' => 'auth:sanctum'], function () {
...
Route::apiResource('categories', CategoryController::class);
});
```
## Tests
When the `Test Cases` option is checked, LaraJS automatically generates integration tests using [Pest PHP](https://pestphp.com/).
```php
<?php
uses(WithFaker::class);
beforeEach(function () {
$faker = $this->faker;
$this->data = [
// faker
];
});
test('get list categories -> 200', function () {
Category::factory()->count(5)->create();
// Call Api
// Expect
});
test('show a category -> 200', function () {
$category = Category::factory()->create();
// Call Api
// Expect
});
test('store a category -> 201', function () {
// Call Api
// Expect
});
test('update a category -> 200', function () {
$category = Category::factory()->create();
// Call Api
// Expect
});
test('destroy a category -> 200', function () {
$category = Category::factory()->create();
// Call Api
// Expect
});
```
**Running Tests**
```php
php artisan test
```