Module Controllers
Introduction
In Concord CRM, the backend (Laravel) and front-end (Vue) are separate entities. The backend is responsible for storing and providing data, while the front-end processes and displays this data to the user.
When developing new modules, it's recommended to build a module API to enable interaction between the front-end and the backend. For instance, when the front-end needs to create an invoice, it sends an HTTP request to the backend. The backend then creates the invoice, sends an email, and returns the created invoice data, which the front-end displays to the user.
Creating modules involves building an API that integrates seamlessly with the existing features of Concord CRM. This ensures that new functionalities works fine within the established system.
Creating API Controller
To create an API controller, you should place the controller in the module app/Http/Controllers/Api
directory, this will ensure to separate the API related controllers from any web
controllers if needed to be added later.
// modules/Invoices/app/Http/Controllers/Api
namespace Modules\Invoices\Http\Controllers\Api;
use Modules\Core\Http\Controllers\ApiController;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Modules\Invoices\Models\Invoice;
class InvoiceStatusController extends ApiController
{
public function update(string $id, string $status, Request $request) : JsonResponse
{
$invoice = Invoice::findOrFail($id);
$this->authorize('update', $invoice);
match($status) {
'paid' => $invoice->markAsPaid(),
default => abort("Invalid Status", JsonResponse::HTTP_CONFLICT),
};
return $this->response(new InvoiceResource($invoice), JsonResponse::HTTP_OK);
}
}
Refer to Laravel controllers documentation for more information if you are not familiar on how controllers work.
When using the resources feature in Concord CRM, you don't need to create controllers for the following actions:
Verb | URI |
---|---|
GET | /invoices |
POST | /invoices |
GET | /invoices/{invoice} |
PUT/PATCH | /invoices/{invoice} |
DELETE | /invoices/{invoice} |
Registering API Routes
When you create a module with the module:make
command, the scaffoling module code will already register the API related route groups and will create an routes/api.php
file.
You should use this file to register any API routes for the module.
// modules/Invoices/routes/api.php
use Illuminate\Support\Facades\Route;
use Modules\Invoices\Http\Controllers\Api\InvoiceStatusController;
Route::middleware('auth:sanctum')->group(function () {
Route::post('/invoices/{invoice}/{status}', [InvoiceStatusController::class, 'update']);
});
All routes registered in the api.php
file, will be prefixed with api
, for example, the route we registered above will be accessible under the /api/invoices/{invoice}/{status}
endpoint.
Refer to Laravel routing documentation for more information if you are not familiar on how routing work.
Registering Web Routes
When you create a module using the module:make
command, the web routes by default will be disabled, if you need to register web routes, in the module RouteServiceProvider.php
file uncomment the web route registration.
The module map
method should look like this:
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
In the module routes
directory, there should be a web.php
file responsible for registering all the web middleware routes.
// modules/Invoices/routes/web.php
use Illuminate\Support\Facades\Route;
Route::middleware(['auth', 'admin'])->group(function () {
Route::get(...);
});
Making HTTP Requests
To make HTTP requests from the front-end, you can use Innoclapps.request()
, please refer to the dedicated frontend documentation.
<template> {{ invoice ? invoice.number : ''}} </template>
<script setup>
import { onMounted, ref } from "vue";
const invoice = ref(null);
async function fetchInvoice() {
const { data } = await Innoclapps.request("/invoices/1");
invoice.value = data;
}
async function updateInvoice() {
const { data } = Innoclapps.request().put("/invoices/1", {
number: 1,
});
invoice.value = data;
}
onMounted(fetchInvoice);
</script>
By calling Innoclapps.request()
you will receive Axios instance pre-configured for Concord CRM with correct API prefix that you can use to make HTTP request to the specified route URL.