Git Product home page Git Product logo

golang-restapi's Introduction

MEMBUAT REST API DENGAN GOLANG, ECHO, GORM DAN MYSQL

Menjalankan Program

  • Install GO 1.21.4 or newer
  • Create Database with fields id_item, nama_item, unit, stok, and harga_satuan
  • Clone github repository https://github.com/mazufik/GOLANG-RESTAPI.git
  • Copy environtment cp config.example.json config.json
  • run go mod tidy
  • run go run main.go

Tutorial

Tahap Pertama

Langkah pertama buat sebuah database terlebih dahulu, misalnya kita buat database eshop. Kemudian buat satu buah tabel dengan nama item dengan field sebagai berikut.

PK id_item int autoincrement
nama_item varchar(100)
unit enum('kg','pcs')
stok int
harga_satuan float

Tahap Kedua

Buat sebuah folder project dengan nama golang-restapi, lalu lakukan inisialisasi project golang dengan perintah go mod init golang-restapi.

Setelah dilakukan inisialisasi project golang, buka project tersebut dengan text editor atau IDE favorit teman-teman. disini saya akan menggunakan text editor vscode. Lalu buka terminal dari text editor install depedensi yang diperlukan yaitu gorm, viper dan echo dengan cara go get gorm.io.gorm, go get github.com/spf13/viper dan go get github.com/labstack/echo.

Selanjutnya pertama-tama kita akan membuat config untuk databasenya, buat file config.json di root project dan buat sebuah folder di dalam project kita dengan nama config.

{
  "database": {
    "host": "hostname",
    "port": "portnya",
    "dbname": "nama database",
    "username": "nama user database",
    "password": "password database"
  }
}

Lalu didalam folder tersebut buat file dengan nama database.go.

  • file database.go
package config

import (
 "github.com/spf13/viper"
 "gorm.io/driver/mysql"
 "gorm.io/gorm"
)

func InitDB() *gorm.DB {
 viper.SetConfigFile("config.json")
 viper.AddConfigPath(".")

 err := viper.ReadInConfig()
 if err != nil {
  panic(err)
 }

 host := viper.GetString("database.host")
 port := viper.GetString("database.port")
 dbname := viper.GetString("database.dbname")
 username := viper.GetString("database.username")
 password := viper.GetString("database.password")

 dsn := username + ":" + password + "@tcp(" + host + ":" + port + ")/" + dbname

 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{SkipDefaultTransaction: true})

 if err != nil {
  panic("Can't connect to database")
 }

 return db
}

Tahap Ketiga

Pada project kita nanti, kita akan menerapkan repository pattern tapi akan saya sesuaikan dengan kebiasaan saya ya patternya.

Pertama buat folder dengan nama domain di dalam root project kita. Lalu di dalam folder domain buat folder item dan di dalamnya buat folder models, repositories, controllers, dan services.

Kita akan mulai dari models ya, buat sebuah fil baru di dalam folder models dengan nama item.go.

  • file /domain/item/models/item.go
package models

type Item struct {
 IdItem      int     `json:"id_item" gorm:"column:id_item;primaryKey;autoIncrement"`
 NamaItem    string  `json:"nama_item" gorm:"column:nama_item"`
 Unit        string  `json:"unit" gorm:"column:unit"`
 Stok        int     `json:"stok" gorm:"column:stok"`
 HargaSatuan float64 `json:"harga_satuan" gorm:"column:harga_satuan"`
}

func (Item) TableName() string {
 return "item"
}

Tahap Keempat

Setelah kita membuat model, kita lanjutkan membuat repositorynya. Untuk membuat repositorynya buat sebuah file dengan nama item_repository.go di dalam folder /domain/item/repositories/.

  • file /domain/item/repositories/item_repository.go
package repositories

import (
 "github.com/mazufik/GOLANG-RESTAPI/domain/item/models"
 "gorm.io/gorm"
)

type dbItem struct {
 Conn *gorm.DB
}

// Create implements ItemRepository.
func (db *dbItem) Create(item models.Item) error {
 return db.Conn.Create(item).Error
}

// Delete implements ItemRepository.
func (db *dbItem) Delete(idItem int) error {
 return db.Conn.Delete(&models.Item{IdItem: idItem}).Error
}

// GetAll implements ItemRepository.
func (db *dbItem) GetAll() ([]models.Item, error) {
 var data []models.Item
 result := db.Conn.Find(&data)
 return data, result.Error
}

// GetById implements ItemRepository.
func (db *dbItem) GetById(idItem int) (models.Item, error) {
 var data models.Item
 result := db.Conn.Where("id_item", idItem).First(&data)
 return data, result.Error
}

// Update implements ItemRepository.
func (db *dbItem) Update(idItem int, item models.Item) error {
 return db.Conn.Where("id_item", idItem).Updates(item).Error
}

type ItemRepository interface {
 Create(item models.Item) error
 Update(idItem int, item models.Item) error
 Delete(idItem int) error
 GetById(idItem int) (models.Item, error)
 GetAll() ([]models.Item, error)
}

func NewItemRepository(Conn *gorm.DB) ItemRepository {
 return &dbItem{Conn: Conn}
}

Tahap Kelima

Setelah kita selesai dengan repository, tahap selanjutnya kita akan membuat service. di service ini kita akan membuat logic dari aplikasi yang kita bangun. Buat sebuah file dengan nama item_service.go didalam folder /domain/item/services/.

Sebelum kita lanjut ke item_service, kita buat dulu sebuah folder di root project dengan nama helpers folder ini berfungsi untuk menyimpan fungsi-fungsi custom yang kita buat. didalam folder helpers buat file dengan nama response.go

  • file /helpers/response.go
package helpers

type Response struct {
 Status   int         `json:"status"`
 Messages string      `json:"messages"`
 Data     interface{} `json:"data"`
}

Kita lanjutkan ke file item_service.go

  • file /domain/item/services/item_service.go
package services

import (
 "fmt"

 "github.com/mazufik/GOLANG-RESTAPI/domain/item/models"
 "github.com/mazufik/GOLANG-RESTAPI/domain/item/repositories"
 "github.com/mazufik/GOLANG-RESTAPI/helpers"
 "gorm.io/gorm"
)

type itemService struct {
 itemRepo repositories.ItemRepository
}

// Create implements ItemService.
func (service *itemService) Create(item models.Item) helpers.Response {
 var response helpers.Response
 if err := service.itemRepo.Create(item); err != nil {
  response.Status = 400
  response.Messages = "Failed to create a new item"
 } else {
  response.Status = 200
  response.Messages = "Success to create a new item"
 }
 return response
}

// Delete implements ItemService.
func (service *itemService) Delete(idItem int) helpers.Response {
 var response helpers.Response
 if err := service.itemRepo.Delete(idItem); err != nil {
  response.Status = 400
  response.Messages = fmt.Sprint("Failed to delete item: ", idItem)
 } else {
  response.Status = 200
  response.Messages = "Success to delete item"
 }
 return response
}

// GetAll implements ItemService.
func (service *itemService) GetAll() helpers.Response {
 var response helpers.Response
 data, err := service.itemRepo.GetAll()
 if err != nil {
  response.Status = 400
  response.Messages = "Failed to get all item"
 } else {
  response.Status = 200
  response.Messages = "Success to get all item"
  response.Data = data
 }
 return response
}

// GetById implements ItemService.
func (service *itemService) GetById(idItem int) helpers.Response {
 var response helpers.Response
 data, err := service.itemRepo.GetById(idItem)
 if err != nil {
  response.Status = 404
  response.Messages = fmt.Sprintf("Item %d not found", idItem)
 } else {
  response.Status = 200
  response.Messages = "Success to get all item"
  response.Data = data
 }
 return response
}

// Update implements ItemService.
func (service *itemService) Update(idItem int, item models.Item) helpers.Response {
 var response helpers.Response
 if err := service.itemRepo.Update(idItem, item); err != nil {
  response.Status = 400
  response.Messages = fmt.Sprint("Failed to update item: ", idItem)
 } else {
  response.Status = 200
  response.Messages = "Success to update item"
 }
 return response
}

type ItemService interface {
 Create(item models.Item) helpers.Response
 Update(idItem int, item models.Item) helpers.Response
 Delete(idItem int) helpers.Response
 GetById(idItem int) helpers.Response
 GetAll() helpers.Response
}

func NewItemService(db *gorm.DB) ItemService {
 return &itemService{itemRepo: repositories.NewItemRepository(db)}
}

Tahap Keenam

Pada tahap ini kita akan masuk ke controllers, buat file dengan nama item_controller.go di dalam folder /domain/item/controllers.

  • file /domain/item/controllers/item_controller.go
package controllers

import (
 "net/http"
 "strconv"

 "github.com/labstack/echo/v4"
 "github.com/mazufik/GOLANG-RESTAPI/domain/item/models"
 "github.com/mazufik/GOLANG-RESTAPI/domain/item/services"
)

type ItemController struct {
 itemService services.ItemService
}

func (controller ItemController) Create(c echo.Context) error {
 type payload struct {
  NamaItem    string  `json:"nama_item" validate:"required"`
  Unit        string  `json:"unit" validate:"required"`
  Stok        int     `json:"stok" validate:"required"`
  HargaSatuan float64 `json:"harga_satuan" validate:"required"`
 }

 payloadValidator := new(payload)

 if err := c.Bind(payloadValidator); err != nil {
  return err
 }

 result := controller.itemService.Create(models.Item{NamaItem: payloadValidator.NamaItem, Unit: payloadValidator.Unit, Stok: payloadValidator.Stok, HargaSatuan: payloadValidator.HargaSatuan})

 return c.JSON(http.StatusOK, map[string]interface{}{
  "data": result,
 })
}

func (controller ItemController) Update(c echo.Context) error {
 type payload struct {
  NamaItem    string  `json:"nama_item" validate:"required"`
  Unit        string  `json:"unit" validate:"required"`
  Stok        int     `json:"stok" validate:"required"`
  HargaSatuan float64 `json:"harga_satuan" validate:"required"`
 }

 payloadValidator := new(payload)

 if err := c.Bind(payloadValidator); err != nil {
  return err
 }

 idItem, _ := strconv.Atoi(c.Param("id_item"))
 result := controller.itemService.Update(idItem, models.Item{NamaItem: payloadValidator.NamaItem, Unit: payloadValidator.Unit, Stok: payloadValidator.Stok, HargaSatuan: payloadValidator.HargaSatuan})

 return c.JSON(http.StatusOK, map[string]interface{}{
  "data": result,
 })
}

func (controller ItemController) Delete(c echo.Context) error {
 idItem, _ := strconv.Atoi(c.Param("id_item"))
 result := controller.itemService.Delete(idItem)

 return c.JSON(http.StatusOK, map[string]interface{}{
  "data": result,
 })
}

func (controller ItemController) GetAll(c echo.Context) error {
 result := controller.itemService.GetAll()

 return c.JSON(http.StatusOK, map[string]interface{}{
  "data": result,
 })
}

func (controller ItemController) GetById(c echo.Context) error {
 idItem, _ := strconv.Atoi(c.Param("id_item"))
 result := controller.itemService.GetById(idItem)

 return c.JSON(http.StatusOK, map[string]interface{}{
  "data": result,
 })
}

func NewItemController(db *gorm.DB) ItemController {
 service := services.NewItemService(db)
 controller := ItemController{
  itemService: service,
 }

 return controller
}

Tahap Ketujuh

Pada tahap ini, kita akan membuat file main.go nya di dalam folder root project kita.

  • file main.go
package main

import (
 "github.com/labstack/echo/v4"
 "github.com/mazufik/GOLANG-RESTAPI/config"
 "github.com/mazufik/GOLANG-RESTAPI/domain/item/controllers"
 "github.com/spf13/viper"
)

func main() {
 viper.SetConfigFile("config.json")
 viper.AddConfigPath(".")
 db := config.InitDB()

 route := echo.New()
 apiV1 := route.Group("api/v1/")

 itemController := controllers.NewItemController(db)
 apiV1.POST("item/create", itemController.Create)
 apiV1.PUT("item/update/:id_item", itemController.Update)
 apiV1.DELETE("item/delete/:id_item", itemController.Delete)
 apiV1.GET("item/get_all", itemController.GetAll)
 apiV1.GET("item/detail/:id_item", itemController.GetById)

 route.Logger.Print("Starting ", viper.GetString("server.appName"))
 route.Logger.Fatal(route.Start(":" + viper.GetString("server.appPort")))
}

golang-restapi's People

Contributors

mazufik avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.