Go Gin ile Tam Kapsamlı CRUD Mikroservis medium içeriğim

188 views
Skip to first unread message

Alper Reha YAZGAN

unread,
Feb 15, 2022, 6:21:43 AM2/15/22
to Golang Türkiye
Herkese merhabalar,
     Go dili hakkında Türkiye'de topluluk var mı diye küçük bir araştırma yaptığımda bu grubu gördüm ve hemen katıldım😃. Go dili Web sunucu tarafında Gin frameworkü ve bir web mimarisinde kullanılan üçüncü parti uygulamaların hepsinin kullanıldığı (Redis, Postgresql, NATS, S3) demo içerikli bir yazı yazdım. Bu yazımı bu platformda paylaşıp ekosisteme benim de katkım olsun istedim. İlgili yazıma aşağıdan erişebilirsiniz. Umarım güzel işler ve paylaşımlarda bulunuruz.
İyi günler.

Go Gin Framework ile Tam Kapsamlı Mikroservis CRUD Uygulaması Yazalım:

Ozgur K

unread,
Feb 15, 2022, 7:23:28 AM2/15/22
to gola...@googlegroups.com

Alper merhaba,

guzel bir is cikarmissin keyifle okudum ve test ettim. Sanirim ihtiyaci olan herkes kodlarinizdan ve mimarinizden faydalanabilir ve sanirim bazi feedback'lara aciksiniz. O nedenle yazmak isitedim.

Oncelikle dilerseniz Reddit veya Twitter uzerinde de tag'layarak daha buyuk bir Go camiasinin kodlarinizdan haberdar olmaasini da saglayabilirsiniz. Reddit veya Twitter uzerinde paylasim yaptiginizda #golang etiketini tag'ladiginizda auto-bot'larin bunu anons ettigini saniyorum, daha fazla feedback icin iyi olabilir :)

Kod kismina gelecek olursak, Microservice yaklasimi da guzel olabilirdi. Yani tek bir isi yapan butun kodlarin run oldugu main.go yerine bazi fonksiyonlari package olarak kullanarak aktif pasif sekilde rebuild edebilirsiniz.Ornegin bir kullanici PostgreSQL kullanmak istemiyorsa "package postgresql" iptal edebilir ve kendi MySQL fonksiyonlarini yazarak "package mysql" import edebilirdi. Bu da structure olarak soyle olabilir.

$ mkdir go-crud-boilerplate
$ cd go-crud-boilerplate
$ mkdir -p platform platform/postgresql platform/nats platform/redis platform/minio

Her mikroservisin kendi kodu package postgresql package nats package redis package minio gibi baslar ve ana main.go uzerinde 

import (
"platform/postgresql"
"platform/nats"
"platform/redis"
"platform/minio"
)

bu sekilde import edebilirdiniz. Bu sayede Go'nun package yapisini da kullanmis olur ve daha mikro fonksiyonlari etkin kilmis olurdunuz. Bence tum route tanimlarini ornegin yeni bir route() fonksiyonu cagirarak burada tanimlayabilirsiniz.

func routes() {
r := gin.Default()
r.GET("/", home)
r.GET("/products",  GetProductsHandler)
r.GET(" /cache/:cache_id  ",  GetProductByCacheIdHandler)
r.POST("/products",  CreateProductHandler)
r.DELETE("/products/:id",   DeleteProductHandler)
/products/:id
r.StaticFS("/file", http.Dir("upload"))
r.Run("127.0.0.1:9090")
}

func main() {
routes()
}

Bu sayede hem yeni bir path endpoint eklemek daha pratik olur hem de / path home fonksiyonuna atanarak dilerseniz .html .js gibi statik icerikleri ornegin templates gibi bir klasor icerisinden cagirabilirsiniz.

Middleware kisminda (sanirim Go Web Development jargonunda buna middleware deniyor) da belki bir statisFS tanimlanmasi ve her product nesnesi icin otomatik bir page yaratilmasi iyi olabilirdi. r.StaticFS ile /product gibi bir tanim yaparak http.Dir ile her urun icin bir url olusturabilirsiniz. CreateProductHandler endpoint her cagirildiginda 

path := "http://localhost:9090/product/" + createProductDto
c.JSON(http.StatusOK, gin.H{"product": path})

seklinde her eklenen urun icin ornegin http://localhost:9090/product/urun seklinde bir url olusturabilir hatta bu URL bilgisini product = url seklinde Redis uzerinde tutabilirsiniz ve frontend implementasyonu cok daha kolay olur :)

CORS implementasyonlarinda artik POST DELETE gibi isleri basit dahi olsa bir auth mekanizmasi ile yapiyorlar. Ben de gecen yaptigim bir projede eger JWT kullanmiyorsam bu yonde bir degisiklige gittim. Bunun icin bir auth fonksiyonu yaratiyorsunuz ve sonrasinda ornegin r.DELETE kismi su sekilde oluyor:

r.DELETE("/products/:id", basicAuth, DeleteProductHandler)

basit auth islemi icin ornek fonksiyon:

func basicAuth(c *gin.Context) {
        user, password, pasAuth := c.Request.BasicAuth()
        if pasAuth && user == "username" && password == "password" {
                log.WithFields(log.Fields{
                "user": user,
                }).Info("Kullanici dogrulandi.")
                } else {
                c.Abort()
                c.Writer.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
                return
        }
}

Bundan sonra DELETE edilecek REST request'lerin basina username password ekleniyor.

$ curl -X GET "http://username:password@localhost:9090//products/:id

Bu veya baska yontemler ornegin JWT ya da belki SQL uzerinde bir token tutarak ya da bu bir User Authentication gerektiren sistemse POST DELETE fonksiyonlarinin cagirdigi fonksiyona kullanicinin servisi cagirmasi icin auth olma sarti getirilebilir. 

Son olarak eger Github ve Docker Hub kullaniyorsaniz belki de pipeline entegre edebilirsiniz. Sanirim .github/workflows/ diye bir folder icerisinde ornegin create.yml dosyasini olusturarak ve Docker Hub uzerinde bir Token olusturup bunu da kullanarak siz git push ettikten sonra GitHub Actions once kendisi pipeline yaratarak ERR PASS alabilir ve bundan sonra Docker Hub uzerinde otomatik yeni tag ile yaziliminiz olusturulabilir :)

Umarim uzun bir mail olmamistir ve size bazi fikirler paylasabilmisimdir.

Happy Coding!

-- Ozgur

Alper Reha YAZGAN <alpe...@gmail.com>, 15 Şub 2022 Sal, 15:22 tarihinde şunu yazdı:

Alper Reha YAZGAN

unread,
Feb 15, 2022, 8:58:16 AM2/15/22
to Golang Türkiye
Merhabalar,

     Öncelikle geri bildiriminiz için çok teşekkür ederim. Ben genel olarak kendi kodlarımı yazarken direkt olarak kodlarımı copy-paste alabileceğim bir repository olmasını düşünerek kodlamıştım. Authentication'ı da şu an geliştirme yaptığım projelerimde local-auth, OAuth gibi seçenekleri projeye göre farklı farklı kullandığım için orayı eklememeyi tercih etmiştim. Ancak sizin dediğiniz gibi "platform/" dizini içerisinde bir dosya düzenlemesine gidebilirsem çok daha verimli bir proje yapılanması gerçekleşeceğini geri bildiriminizle farkına vardım. Eğer otomatik CI/CD entegresi için ayarlamalar yapabilirsem belki OpenFaas uygulaması Go kısmı ve Firebase Cloud Functions Go SDK gibi yapılara destek veya alternatif olabilecek plugin'lenebilir ve kolay geliştirilebilir açık kaynak bir projeye bile dönüşebileceğini farkettim. Çok teşekkür ederim. Ben makaleyi geri bildirimlere göre güncelliyorum zaten. İnceleyeceğim.

Çok teşekkürler.  

- Statik dosyalar routing,retrieving, rendering,
- Github Actions entegrasyonu
- Authentication eklenmesi
- Dosya düzeni


15 Şubat 2022 Salı tarihinde saat 15:23:28 UTC+3 itibarıyla zgr şunları yazdı:
Reply all
Reply to author
Forward
0 new messages