I'm facing a little issue with Form Request Validation and how to handle it with one API route.
The resource that I need to create depends on an other resource.
(Here an EmailSettings
belongs to a Tenant)
So the look of my route should be something like : /api/tenants/{id}/email_settings
And my request validation expects several fields including the tenantId
:
public function rules() {
return [
'email' => 'bail|required|email|unique:email_settings,email',
'name' => 'bail|required',
'username' => 'bail|required',
'password' => 'bail|required'
'imapHost' => 'bail|required',
'imapPort' => 'bail|required',
'imapEncryption' => 'bail|required',
'imapValidateCert' => 'bail|required',
'smtpHost' => 'bail|required',
'smtpPort' => 'bail|required',
'smtpEncryption' => 'bail|required',
'tenantId' => 'bail|required',
];
}
And I send the request like this :
try {
const response = await this.tenantForm.post('/api/tenants')
let newTenant = helpers.getNewResourceFromResponseHeaderLocation(response)
let tenantId = parseInt(newTenant.id);
try {
await this.emailSettingsForm.post('/api/tenants/' + tenantId + '/email_settings')
this.requestAllTenants()
} catch ({response}) {
$('.second.modal').modal({blurring: true, closable: false}).modal('show');
}
} catch ({response}) {
$('.first.modal').modal({blurring: true}).modal('show');
}
So the tenantId
is passed as a parameter and not in the request body to respect the REST convention.
But the problem is in my Controller, when I merge the data to create the resource, the validation has already took place only on body data before the merge.
public function store(EmailSettingValidation $request, $tenant_id) {
$emailSetting = $this->emailSettingService->create(
array_merge($request->all(), compact($tenant_id))
);
return $this->response->created($emailSetting);
}
So what is the best way to handle it properly?
tenantId
rule and check it manually?Any suggestions?
So the solution I found to trigger 404 is the following :
Try to throw this Exception with the findOrFail method if invalid ID :
public function store(EmailSettingValidation $request, $tenant_id) {
Tenant::findOrFail($tenant_id);
$emailSetting = $this->emailSettingService->create(
array_merge($request->all(), ['tenantId' => $tenant_id])
);
return $this->response->created($emailSetting);
}