Golang REST API ve CRUD İşlemleri

·Golang·
#Golang#REST API#CRUD#Gofiber

Golang REST API ve CRUD İşlemleri

Bugün Golang ile Gofiber kullanarak yüksek performanslı bir REST API nasıl geliştirilir bunun üzerine konuşacağız. 

Gofiber framework kullanmamızın sebebini şu şekilde listeleyebiliriz:

  • Yüksek performans ve düşük bellek kullanımı
  • Hızlı server-side programlama
  • Kütüphane tarafından sağlanan middlewarelar
  • Kolay rotalama

 

Proje Oluşturma

Genel olarak konuya giriş yaptığımıza göre Go projemizi oluşturarak devam edebiliriz. Boş bir Go projesi oluşturmak için şu işlemleri yapalım.

$ mkdir restapi

$ go mod init github.com/USERNAME/REPO_NAME

Bu işlemleri yaptıktan sonra gerekli klasörler ve dosyalar oluşacaktır. Şimdi proje dizinimizde main.go dosyamızı oluşturalım, ardından gofiber kütüphanesini projemize aşağıdaki komut ile ekleyelim.

$ go get github.com/gofiber/fiber/v2

 

Klasör Yapısı

/app

Bu klasör bizim genel Fiber uygulamamıza dair fonksiyonları barındırmalıdır. Şu şekilde kapsamlandırabiliriz.

  • controllers
    Rotalarda kullanılacak controllerları burada tanımlarız.
  • models
    Uygulamamızdaki modelleri bu klasör altında oluşturmalıyız.

/pkg

  • configs
    Bu klasörde uygulamamıza ait konfigürasyon dosyalarını tutabiliriz.
  • middleware
    Bu klasörde fiber uygulamamız için gerekli middlewareları oluşturabiliriz.
  • routes
    Bu klasör içerisinde projemize ait rotaları tutabiliriz.
  • utils
    Bu klasörde sunucumuzu başlatan, hataları kontrol eden veya uygun gördüğümüz dosyaları oluşturabiliriz.

 

/platform

  • cache
    Bu klasörde kullanacağımız önbellekleme çözümünü implemente edebiliriz.
  • database
    Veritabanı bağlantılarını ve diğer işlemleri yapacağımız kısım.
  • migrations
    Migrationları oluşturacağımız klasör

Fiber Sunucusu

Bunun için öncelikle pkg/utils altında server.go dosyamızı oluşturalım ve içeriğini aşağıdaki şekilde ekleyelim.

package utils

import (
    "fmt"
    "log"

    "github.com/gofiber/fiber/v2"
)

func CreateServer(port int) {
    // Create Fiber App
    app := fiber.New()

    // Start server
    log.Fatal(app.Listen(fmt.Sprintf(":%d", port)))
}

Ardından bu fonksiyona bir port değişkeni vererek main.go içerisinde şu şekilde çağırabiliriz.

Bu fonksiyon içerisinde middlewarelarımızı ve rotalarımızı kaydedeceğiz.

 

Örnek main.go içeriği:

package main

import "github.com/dogukanoksuz/go-rest-api-example/pkg/utils"

func main() {
    utils.CreateServer(3000)
}

 

Model Oluşturmak

Genel olarak projemizin klasör yapısından bahsettiğimize göre bu tarz bir yapıyı oluşturalım. 

Ardından models klasörümizin içerisinde ilk modelimizi oluşturalım. Ben post yani gönderi isminde bir model oluşturacağım. Dosya içeriğini aşağıdaki gibi tanımlayabiliriz.

package models

import (
    "github.com/google/uuid"
    "gorm.io/gorm"
)

type Post struct {
    ID      string `gorm:"primary_key"`
    Title   string
    Content string `gorm:"type:text"`
}

func (post *Post) BeforeCreate(tx *gorm.DB) error {
    post.ID = uuid.NewString()
    return nil
}

Oluşturduktan sonra ilk modelimiz hazır. Genel olarak detaylarından bahsetmek gerekirse ID alanı için UUID oluşturuyoruz. Bunun için de GORM’un pre-hooklarından faydalanarak bir UUID tanımlıyoruz. 

 

Veritabanı Bağlantısı

Öncelikle kendi ortamınızda bir veritabanı sunucusuna sahip olmanız gerekmektedir. Ben devilbox kullanarak bir MariaDB instanceı oluşturdum. Siz de benzer programlarla veritabanınızı oluşturun.

Bu işlemin ardından platform/database klasörü altında mysql.go isminde bir dosya oluşturun.

package database

import (
    "fmt"
    "os"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var Conn *gorm.DB

func Init() error {
    var err error

    dsn := fmt.Sprintf(
        "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
        "DB_USER",
        "DB_PASS",
        "DB_HOST",
        "DB_PORT",
        "DB_NAME",
    )

    Conn, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})

    if err != nil {
        return err
    }

    return nil
}

Yukarıdaki şekilde tanımlama yaptıktan sonra DB_USER gibi boşlukları kendi veritabanı bilgileriniz ile değiştirin. Ardından database.Init() şeklinde server.go dosyanız içerisinde çağırımı yaparak sunucu başlamadan önce veritabanı bağlantınızı açabilirsiniz.

 

Migrationlar

Migration işlemi oluşturduğumuz modellerin otomatik şekilde veritabanında tablolarının eklenmesi işlemidir. Bunun için platform/migrations altında migrate.go isminde bir dosya oluşturalım ve içeriğini aşağıdaki şekilde girelim.

package migrations

import (
    "github.com/dogukanoksuz/go-rest-api-example/app/models"
    "github.com/dogukanoksuz/go-rest-api-example/platform/database"
)

func Migrate() {
    database.Conn.AutoMigrate(&models.Post{})
}

Bu kısımdaki AutoMigrate fonksiyonu GORM’un içerisinde gelen bir fonksiyondur. Diğer oluşturduğunuz modeller (varsa) bu kısımda tanımlayarak uygulama başlangıcında tablolarının oluşturulmasını sağlayabilirsiniz. Bu fonksiyonu CreateServer fonksiyonu altında database.Init fonksiyonundan hemen sonra çağırabiliriz.

 

Kontrolcü Oluşturmak

Kontrolcüler projemizin önemli bir ayağını oluşturmaktadır. Fiber tarafında ismi Handler olarak geçmektedir ve rotalarımızın ucunu bağladığımız Go fonksiyonlarına kontrolcü demekteyiz. Kontrolcüler bizim için postlarımızı listeleme, oluşturma, güncelleme ve silme işlemlerini yapabilir.

GORM ve Fiber kullanarak listeleme ve oluşturma işlemlerini örnek olarak inceleyelim.

Oluşturma (Create)

package post

import (
    "github.com/dogukanoksuz/go-rest-api-example/app/models"
    "github.com/dogukanoksuz/go-rest-api-example/platform/database"
    "github.com/gofiber/fiber/v2"
)

func Create(ctx *fiber.Ctx) error {
    post := models.Post{}

    if err := ctx.BodyParser(&post); err != nil {
        return ctx.Status(503).JSON(err)
    }

    if err := database.Conn.Create(&post).Error; err != nil {
        return ctx.Status(503).JSON(err)
    }

    return ctx.JSON(post)
}

Bu dosyayı app/controllers/post/create.go olarak oluşturalım ve inceleyelim. Öncelikle Fiber’ın BodyParser fonksiyonunu kullanarak bodyden gelen JSON’u parse edelim. Ardından database.Conn.Create diyerek girdimizi veritabanına ekleyelim. İşlemlerin sonunda da kullanıcıya JSON olarak oluşturulan gönderimizi gönderebiliriz.

Listeleme (Index/List)

package post

import (
    "github.com/dogukanoksuz/go-rest-api-example/app/models"
    "github.com/dogukanoksuz/go-rest-api-example/platform/database"
    "github.com/gofiber/fiber/v2"
)

func Index(ctx *fiber.Ctx) error {
   posts := []models.Post{}
    database.Conn.Find(&posts)

    return ctx.JSON(posts)
}

GORM ile bir modelin girdilerini listelemek istediğimizde yukarıdaki yola başvurabiliriz. Find fonksiyonu bizim için tüm postları getirecektir ve bunu da kullanıcılara JSON olarak döndürebiliriz.

 

Rota Tanımlamak

Rotalar REST sunucumuzda hangi uçların hangi fonksiyonları çağıracağını, alacağı parametreleri vb. tanımladığımız yerdir. Gelin örnek olarak yukarıdaki iki fonksiyonun rotalarını tanımlayalım.

Bunun pkg/routes altında post.go dosyamızı oluşturabiliriz. Bu dosyanın içeriği aşağıdaki gibi olmalıdır.

package routes

import (
    "github.com/dogukanoksuz/go-rest-api-example/app/controllers/post"
    "github.com/gofiber/fiber/v2"
)

func PostRoutes(app *fiber.App) {
    // List All Posts
    app.Get("/posts", post.Index)

    // Create Post
    app.Post("/post", post.Create)
}

Bu PostRoutes fonksiyonumuzu da CreateServer altında fiber app oluşturduktan hemen sonra çağırabiliriz. routes.PostRoutes(app) şeklinde tanımlamayı yaptığımızda rotalarımız kullanıma hazır olacaktır.

 

Derleme ve Denemeler

Projeyi çalıştırmak için go run main.go şeklinde başlatabilir ya da go build diyerek oluşan executable’ı çalıştırabiliriz.

Temel olarak oluşturduğunuz REST API’ı derleyip denemeler yapın. Bunun için Postman programını veya sevdiğiniz bir REST clienti kullanabilirsiniz.

Rotalarınıza 127.0.0.1:3000/posts şeklinde erişebilirsiniz. Eğer veritabanında girdi oluşturulmuş ise başarılı şekilde dönüşümüzü alacağız.

 

Tamamlanmış Proje

dogukanoksuz/go-rest-api-boilerplate: Golang REST API Boilerplate with Gofiber (github.com) altından projenin tamamlanmış haline ulaşabilirsiniz. Post modeli için tüm CRUD işlemlerinin tamamlandığı örnek bu şekilde incelenebilir.

Okuduğunuz için teşekkür ederim. Problemler için GitHub reposu içerisinde issue oluşturabilir veya aşağıdaki yorumlar bölümünü kullanabilirsiniz.