Dalam siaran lepas, kami menganalisis cara komponen simfoni penyeri dan pengesah bertindak sebagai perkhidmatan infrastruktur yang menyediakan alat yang membantu kami melaksanakan tugas biasa dalam aplikasi. Kami juga mengetahui sebab kelas UserInputDTO ialah elemen yang dimiliki oleh domain kami kerana ia mengandungi peraturan perniagaan dan cara mencipta perkhidmatan lapisan aplikasi untuk melaksanakan aliran data mengekstrak dan mengesahkan.
Dalam bahagian kedua ini, kita akan melihat cara mengurus ralat pengesahan dan, seperti yang kita lakukan pada bahagian pertama, kita akan mengenal pasti bahagian mana yang tergolong dalam domain.
Ralat pengesahan dikembalikan oleh komponen pengesah Symfony selepas mengesahkan UserInputDTO mengikut peraturan yang ditetapkan dengan menggunakan kekangan pengesahan.
public function processData(string $content, string $dtoClass): object { $requestData = json_decode($content, true); $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class); $errors = $validator->validate($userInputDTO); if(count($errors) > 0) { throw new ValidationFailedException($errors); } return $userInputDTO }
Seperti yang anda lihat dalam kod di atas, jika kaedah pengesahan menemui ralat, pengecualian jenis ValidationException akan dilemparkan. Dari sini, kami mesti memutuskan cara kami ingin menunjukkan ralat kepada pengguna (domain / peraturan perniagaan) dan alat yang akan kami harapkan supaya ralat sampai kepada pengguna dengan betul (infrastruktur dan aplikasi).
Perkara pertama yang perlu kita ambil kira ialah kita ingin menangkap ralat pengesahan apabila ia berlaku. Untuk mencapai matlamat ini, kami akan bergantung kepada lapisan infrastruktur.
Kernel Symfony dilengkapi dengan set acara kernel terbina dalam untuk mendengar acara khas. Salah satu acara ini ialah acara pengecualian kernel yang dicetuskan apabila pengecualian dilemparkan. Mari kita gunakannya untuk menangkap ralat ValidationException.
class KernelSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ KernelEvents::EXCEPTION => 'onException' ]; } public function onException(ExceptionEvent $event): void { $exception = $event->getThrowable(); if($exception instanceof ValidationFailedException){ // Business rules to build the errors } } }
Seperti yang dapat kita lihat dalam kod di atas, KernelSubscriber terus mendengar acara KernelException dan ia hanya akan melaksanakan beberapa logik apabila pengecualian yang ditangkap ialah contoh ValidationFailedException kelas.
Dari sini, kita mesti menentukan logik yang akan dilaksanakan apabila kaedah onException mengesan bahawa ia adalah ralat pengesahan.
Memandangkan kami bertanggungjawab untuk memutuskan cara kami akan menstrukturkan ralat (kami mentakrifkan peraturan perniagaan tersebut), perkhidmatan yang melaksanakan logik akan menjadi milik domain kami. Jom kodkan
class ValidationErrorsBuilder { public function buildErrors(ValidationFailedException $exception): array { $errors = []; foreach ($exception->getViolations() as $violation) { $errors[$violation->getPropertyPath()] = $violation->getMessage(); } return $errors; } }
Kod ValidationErrorsBuilder agak mudah: ia menggelungkan ralat pelanggaran dan mencipta tatasusunan bersekutu dengan kunci adalah sifat yang menghasilkan ralat dan nilainya ialah mesej ralat.
Kini tiba masanya untuk menggunakan perkhidmatan domain ValidationErrorsBuilder kami. Kami menggunakannya pada kaedah KernelSubscriber onException.
public function processData(string $content, string $dtoClass): object { $requestData = json_decode($content, true); $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class); $errors = $validator->validate($userInputDTO); if(count($errors) > 0) { throw new ValidationFailedException($errors); } return $userInputDTO }
Seperti yang anda lihat, selepas mengetahui bahawa pengecualian ialah ValidationFailedException, kami menggunakan perkhidmatan domain kami untuk mendapatkan tatasusunan ralat pengesahan.
Sekarang, mari lihat kod berikut:
class KernelSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ KernelEvents::EXCEPTION => 'onException' ]; } public function onException(ExceptionEvent $event): void { $exception = $event->getThrowable(); if($exception instanceof ValidationFailedException){ // Business rules to build the errors } } }
Kami telah menambah dan baris baharu di mana kami menetapkan Symfony JsonResponse yang menahan tatasusunan ralat sebagai respons baharu dan kami menyatakan bahawa kod HTTP yang dikembalikan akan menjadi 400 Permintaan Buruk.
Kami telah bergantung pada pemalar Symfony Response HTTP_BAD_REQUEST untuk menentukan kod HTTP respons. Semasa kami bekerja dalam persekitaran fokus Domain, kami mungkin telah mencipta kelas domain tersuai kami (contohnya php enum) tetapi, kerana kami hanya perlu mengendalikan kod HTTP standard dan tidak ada keperluan khusus untuk penyesuaian, kami boleh menggunakan Kod HTTP Symfony walaupun ini menjadikan kita lebih bergantung pada rangka kerja.
Kami belum bercakap tentang lapisan aplikasi setakat ini. Kami telah mengatakan pada awal artikel bahawa rangka kerja Symfony datang dengan acara terbina dalam yang berguna seperti yang telah kami gunakan: Acara pengecualian kernel. Selain itu, rangka kerja symfony juga menawarkan kami EventSubscriberInterface yang dengannya kami boleh mencipta pelanggan acara tersuai kami dan mendengar acara yang kami perlukan.
Daripada maklumat ini, kita boleh membuat kesimpulan bahawa symfony menawarkan kepada kita acara pengecualian kernel dan EventSubscriberInterface tetapi kita perlu menggunakan antara muka untuk mencipta pelanggan yang menyatakan acara yang akan kita dengar. Jom sambung semula:
Adakah ini terdengar biasa kepada anda? Ya, pelanggan acara bertanggungjawab untuk orkestrasi dan penyelarasan mengurus ralat pengesahan selepas pengecualian dilemparkan supaya kami boleh mengatakan bahawa pelanggan acara akan bertindak sebagai perkhidmatan aplikasi.
Jika kita ingin melangkah lebih jauh, kita boleh membuat perkhidmatan lapisan aplikasi dan menggunakannya dalam pelanggan.
class ValidationErrorsBuilder { public function buildErrors(ValidationFailedException $exception): array { $errors = []; foreach ($exception->getViolations() as $violation) { $errors[$violation->getPropertyPath()] = $violation->getMessage(); } return $errors; } }
public function onException(ExceptionEvent $event): void { $exception = $event->getThrowable(); if($exception instanceof ValidationFailedException){ $errors = $this->validationErrorsBuilder->buildErrors($exception); } }
Kini, ValidationErrorsProcessor akan bertindak sebagai perkhidmatan aplikasi yang menyelaraskan pengurusan respons ralat pengesahan dan menggunakan perkhidmatan domain ValidationErrorsBuilder.
Dalam artikel kedua siri ini, kami telah mengenal pasti komponen proses pengurusan ralat pengesahan yang dimiliki oleh domain, elemen infrastruktur yang telah kami gunakan dan cara pelanggan Kernel boleh bertindak sebagai perkhidmatan aplikasi.
Dalam artikel seterusnya, kami akan mengekalkan entiti dalam pangkalan data dan kami akan menganalisis cara memisahkan logik mengubah DTO menjadi entiti yang berterusan.
Atas ialah kandungan terperinci Mencipta aplikasi domain berfokus. Pendekatan Symfony (Mengurus ralat pengesahan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!