DEV Community

Nanpipat Klinpratoom
Nanpipat Klinpratoom

Posted on • Updated on

มาลองทำ gorm repository โดยใช้ Go Generics กันครับ

ปกติแล้วเวลาเราจะทำ service ซักตัว เราจะพบว่าในหลาย ๆ table นั้น จะมีการใช้คำสั่ง query ที่ค่อนข้างจะเป็นรูปแบบที่ซ้ำ ๆ กัน เช่น การทำ CRUD service ก็จะเป็นการ Create, Find, Update, Delete อะไรทำนองนี้ ซึ่งใน level ของการทำ repository ในโปรเจคเรานั้น หากมีหลาย table ก็อาจจะต้องมีการทำ repository ในหลายรอบที่ต่างออกไป แต่รวม ๆ แล้วคำสั่งข้างในก็จะคล้าย ๆ กัน

วันนี้เราเลยจะมาลองทำให้มี repository แค่หนึ่งไฟล์ แต่ใช้ได้กับหลาย ๆ models หรือหลาย ๆ table กันครับ โดยใช้ gorm กับ go generic กันครับ

มาดูโค้ดในส่วนของ repository กันครับ

อธิบายโค้ดเพิ่มซักนิดนึงครับ ตรง function NewRepository คือการเรียกใช้ repository นี้ โดยการโยน models ใดก็ได้เข้ามา (go generic)

และหลังจากนั้นผมจะสร้าง function อื่น ๆ เพิ่ม เช่นการ Create , FindAll พวกนี้คือการ override function ของ gorm เข้าไป โดยคุณอาจจะไม่ต้องตั้งชื่อตาม gorm ก็ได้ แต่ผมค่อนข้างจะชินในการตั้งแบบนี้ เพราะเวลาอ่าน document ของ gorm จะได้เอามาปรับใช้ได้เลยง่าย ๆ

ส่วนถัดมาก็คือส่วนของ condition ต่าง ๆ เช่น Where , Order และอื่น ๆ ก็จะทำคล้าย ๆ กัน เพียงแค่การ return จะไม่เหมือนกัน เพราะเราสามารถทำได้หลาย ๆ condition มันจึงจะ stack ไปเรื่อย ๆ มากกว่า

โดยการทำ function เหล่านี้ คุณสามารถ custom parameter ที่รับเข้ามาและส่งออกไปได้เลย ทำได้หลากหลายมากมาก ผมอาจจะไม่ได้ยกตัวอย่างที่แปลก ๆ ไว้ เพราะอยากให้เห็นภาพการใช้ go generic ในการรับ type อะไรเข้ามาก็ return สิ่งนั้นออกไปครับ

โอเคครับ ทีนี้มาถึงโค้ดตอนนำไปใช้ จะหน้าตาเป็นแบบนี้

โดยผมจะไม่อธิบายถึงการ inject db เข้ามา หรือการวาง stucture ของโปรเจคนะครับ เพราะคิดว่าแต่ละคนคงมีรูปแบบที่ไม่เหมือนกัน อันนี้ก็จะเป็นตัวอย่างคร่าว ๆ โดยค่า db ที่ผมส่งไปก็จะเป็น type gorm.DB ตามที่ repository ของเราต้องการ และก็อีกค่าเป็นค่า context ที่เราอาจจะต้องใช้ถ้าเราใช้กับ framework หรือ third-party ที่เราอยากจะส่ง context ไปใช้นะครับ

ซึ่งทั้งหมดจะเป็นแค่ concept คร่าว ๆ ในการทำ go generic มาใช้กับการทำ gorm repository คุณสามารถ custom มันเองได้ทั้งหมดตามแต่ที่คุณต้องการครับ

https://github.com/nanpipat-dev/gorm-generic-repository

อันนี้จะเป็นลิ้ง git ที่ผมทำไว้เป็นตัวอย่างสำหรับบทความนี้ครับ หากมีข้อสงสัยหรือมีข้อติติงตรงไหนคอมเม้นบอกได้เลยครับ ขอบคุณที่อ่านมาจนจบครับ 🙏🏻

Top comments (0)