Ini adalah siaran pertama siri yang telah saya putuskan untuk dibuat untuk menerangkan cara saya mengatur aplikasi symfony saya dan cara saya cuba menulis kod sebagai berorientasikan domain yang mungkin.
Di bawah, anda boleh menemui gambarajah alir yang akan saya gunakan semasa semua bahagian siri. Dalam setiap siaran, saya akan memfokuskan pada bahagian konkrit rajah dan saya akan cuba menganalisis proses yang terlibat dan mengesan bahagian mana yang akan menjadi milik domain kami dan cara memisahkan daripada bahagian lain menggunakan lapisan luaran.
Dalam bahagian pertama ini, kami akan menumpukan pada proses pengekstrakan dan pengesahan data. Untuk proses pengekstrakan data, kami akan menganggap bahawa data permintaan diformatkan sebagai JSON.
Berdasarkan fakta bahawa kami tahu bahawa data permintaan terdapat dalam muatan permintaan JSON, mengekstrak muatan permintaan (dalam kes ini mengekstrak bermakna mendapatkan tatasusunan daripada muatan JSON) adalah semudah menggunakan fungsi php json_decode.
class ApiController extends AbstractController { #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])] public function saveAction(Request $request,): JsonResponse { $requestData = json_decode($request->getContent(), true); // validate data } }
Untuk mengesahkan data, kami memerlukan tiga elemen:
Untuk yang pertama, kami akan mencipta DTO (Objek Pemindahan Data) yang akan mewakili data masuk dan kami akan menggunakan atribut kekangan pengesahan Symfony untuk menentukan cara data ini mesti disahkan.
readonly class UserInputDTO { public function __construct( #[NotBlank(message: 'Email cannot be empty')] #[Email(message: 'Email must be a valid email')] public string $email, #[NotBlank(message: 'First name cannot be empty')] public string $firstname, #[NotBlank(message: 'Last name cannot be empty')] public string $lastname, #[NotBlank(message: 'Date of birth name cannot be empty')] #[Date(message: 'Date of birth must be a valid date')] public string $dob ){} }
Seperti yang anda lihat, kami telah menentukan peraturan pengesahan data input kami dalam DTO yang dibuat baru-baru ini. Peraturan ini adalah seperti berikut:
Untuk yang kedua, kami akan menggunakan komponen Symfony normalizer yang dengannya kami akan dapat memetakan permintaan data masuk ke dalam DTO kami.
class ApiController extends AbstractController { #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])] public function saveAction(Request $request, SerializerInterface $serializer): JsonResponse { $requestData = json_decode($request->getContent(), true); $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class); } }
Seperti yang ditunjukkan di atas, kaedah nyahnormalkan melakukan perkara dan dengan satu baris kod, kami mendapatkan DTO kami diisi dengan data masuk.
Akhir sekali, untuk mengesahkan data kami akan bergantung pada perkhidmatan pengesah Symfony yang akan menerima contoh DTO kami yang dinyahnormalkan baru-baru ini (yang akan membawa data masuk) dan akan mengesahkan data mengikut peraturan DTO.
class ApiController extends AbstractController { #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])] public function saveAction(Request $request,): JsonResponse { $requestData = json_decode($request->getContent(), true); // validate data } }
Setakat ini, kami telah membahagikan proses Mengekstrak dan Mengesahkan Data kepada empat bahagian:
Persoalannya sekarang ialah: Manakah antara bahagian ini yang tergolong dalam domain kami?
Untuk menjawab soalan, Mari analisa proses yang terlibat:
1.- Mengekstrak data: Bahagian ini hanya menggunakan fungsi "json_decode" untuk mengubah data masuk daripada json kepada tatasusunan. Ia tidak menambah logik perniagaan jadi ini bukan milik domain.
2.- DTO: DTO mengandungi sifat yang dikaitkan dengan data input dan cara ia akan disahkan. Ini bermakna DTO mengandungi peraturan perniagaan (peraturan pengesahan) supaya ia tergolong dalam domain.
3.- Nyahnormalkan data: Bahagian ini hanya menggunakan perkhidmatan infrastruktur (komponen rangka kerja) untuk menyahnormalkan data menjadi objek. Ini tidak mengandungi peraturan perniagaan jadi ini bukan milik domain kami.
4.- Mengesahkan data: Dengan cara yang sama seperti proses Nyahnormalkan data, proses data yang mengesahkan juga menggunakan perkhidmatan infrastruktur (komponen rangka kerja) untuk mengesahkan data yang masuk . Ini tidak mengandungi peraturan perniagaan kerana ia ditakrifkan dalam DTO jadi ia juga bukan sebahagian daripada domain kami.
Selepas menganalisis mata terakhir, kami boleh membuat kesimpulan bahawa hanya DTO akan menjadi sebahagian daripada domain kami. Kemudian, apa yang kita lakukan dengan kod yang lain?
Secara peribadi, saya suka memasukkan proses jenis ini (mengekstrak, menyahnormalkan dan mengesahkan data) ke dalam lapisan aplikasi atau lapisan perkhidmatan. Kenapa ?, mari perkenalkan lapisan aplikasi.
Ringkasnya, lapisan aplikasi bertanggungjawab untuk orkestrasi dan penyelarasan, meninggalkan logik perniagaan kepada lapisan domain. Selain itu, ia bertindak sebagai perantara antara lapisan domain dan lapisan luaran seperti lapisan pembentangan (UI) dan lapisan infrastruktur.
Bermula daripada definisi di atas, kita boleh memasukkan proses Mengekstrak, Menyahnormalkan dan Mengesahkan ke dalam perkhidmatan dalam lapisan aplikasi sejak:
Sempurna, kami akan mencipta perkhidmatan aplikasi untuk menguruskan proses ini. Bagaimana kita akan melakukannya? Bagaimana kita hendak menguruskan tanggungjawab?
Prinsip Tanggungjawab Tunggal (SRP) menyatakan bahawa setiap kelas harus bertanggungjawab untuk hanya satu bahagian tingkah laku aplikasi. Jika kelas mempunyai pelbagai tanggungjawab, ia menjadi lebih sukar untuk difahami, diselenggara dan diubah suai.
Bagaimanakah ini memberi kesan kepada kita? Mari analisanya.
Setakat ini, kami tahu bahawa perkhidmatan aplikasi kami mesti mengekstrak, menyahnormalkan dan mengesahkan data masuk. Mengetahui perkara ini, adalah mudah untuk mengeluarkan tanggungjawab berikut:
Perlukah kita membahagikan tanggungjawab ini kepada 3 perkhidmatan yang berbeza? Saya tidak fikir begitu. Biar saya terangkan.
Seperti yang telah kita lihat, setiap tanggungjawab diuruskan oleh fungsi atau komponen infrastruktur:
Memandangkan perkhidmatan aplikasi boleh mewakilkan tanggungjawab ini kepada perkhidmatan infrastruktur, kami boleh membuat tanggungjawab yang lebih abstrak (Proses data) dan menyerahkannya kepada perkhidmatan aplikasi.
class ApiController extends AbstractController { #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])] public function saveAction(Request $request,): JsonResponse { $requestData = json_decode($request->getContent(), true); // validate data } }
Seperti yang ditunjukkan di atas, perkhidmatan aplikasi DataProcessor menggunakan fungsi json_decode dan perkhidmatan normalizer dan validator Symfony untuk memproses permintaan input dan mengembalikan DTO yang baru dan disahkan. Jadi kita boleh katakan bahawa perkhidmatan DataProcessor:
Seperti yang anda mungkin perasan, perkhidmatan DataProcessor melemparkan Symfony ValidationException apabila proses pengesahan menemui ralat. Dalam siaran seterusnya siri ini, kami akan belajar cara menggunakan peraturan perniagaan kami untuk menstruktur ralat dan akhirnya membentangkannya kepada pelanggan.
Saya tahu bahawa kami boleh mengalih keluar perkhidmatan DataProcessor dan menggunakan MapRequestPayload sebagai lapisan aplikasi perkhidmatan untuk mengekstrak, menyahnormalkan dan mengesahkan data tetapi, memandangkan konteks artikel ini, saya fikir ia lebih mudah untuk tulis dengan cara ini.
Dalam artikel pertama ini, kami telah menumpukan pada proses Pengekstrakan dan Pengesahan data daripada rajah alir. Kami telah menyenaraikan tugasan yang terlibat dalam proses ini dan kami telah mempelajari cara untuk mengesan bahagian mana yang tergolong dalam domain tersebut.
Mengetahui bahagian mana yang dimiliki oleh domain, kami telah menulis perkhidmatan lapisan aplikasi yang menghubungkan perkhidmatan infrastruktur yang diperintah oleh domain dan menyelaraskan proses pengekstrakan dan pengesahan data.
Dalam artikel seterusnya, kami akan meneroka hangat untuk menentukan peraturan perniagaan kami untuk mengurus pengecualian dan kami juga akan mencipta perkhidmatan domain yang akan bertanggungjawab mengubah DTO Input menjadi entiti yang berterusan.
Atas ialah kandungan terperinci Mencipta aplikasi domain berfokus. Pendekatan Symfony (Bahagian 1). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!