Membuat Simple CRUD Webservice dengan Golang
Pada artikel kali ini saya membahas bagaimana membuat sebuah simple CRUD webservice dengan bahasa GoLang, disini saya menggunakan Echo sebagai minimalis webframeworknya.
pertama buat folder baru di $GOPATH
cd $GOPATH
mkdir simpleapi
lalu buat file app.go
package main
import (
"database/sql"
"simpleapi/handlers"
"github.com/labstack/echo"
_ "github.com/mattn/go-sqlite3"
)
func main() {
e := echo.New()
db := initDB("storage.db")
migrate(db)
// daftar api
e.GET("/tasks", handlers.GetTasks(db))
e.POST("/tasks", handlers.PutTask(db))
e.PUT("/tasks", handlers.EditTask(db))
e.DELETE("/tasks/:id", handlers.DeleteTask(db))
e.Logger.Fatal(e.Start(":8000"))
}
func initDB(filepath string) *sql.DB {
db, err := sql.Open("sqlite3", filepath)
if err != nil {
panic(err)
}
if db == nil {
panic("db nil")
}
return db
}
func migrate(db *sql.DB) {
sql := `
CREATE TABLE IF NOT EXISTS tasks(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name VARCHAR NOT NULL,
status INTEGER
);
`
_, err := db.Exec(sql)
// Exit if something goes wrong with our SQL statement above
if err != nil {
panic(err)
}
}
pada fungsi main, kita mendefiniskan inisiasi echo,
e := echo.New()
lalu langkah selanjutnya adalah inisiasi database, disertai pembuatan tablenya
db := initDB("storage.db")
migrate(db)
selanjutnya define daftar api yang akan kita buat
e.GET("/tasks", handlers.GetTasks(db))
e.POST("/tasks", handlers.PutTask(db))
e.PUT("/tasks", handlers.EditTask(db))
e.DELETE("/tasks/:id", handlers.DeleteTask(db))
selanjutnya untuk menjalankan server pada port 8000, gunakan kode berikut
e.Logger.Fatal(e.Start(":8000"))
langkah selanjutnya buat dua buah folder yakni handlers dan models,
- handlers : digunakan untuk komunikasi dengan models, return dari handlers ini sebaiknya langsung berupa JSON
- models : digunakan untuk akses query ke database
class models/task.go
package models
import (
"database/sql"
)
type Task struct {
ID int `json:"id"`
Name string `json:"name"`
Status int `json:"status"`
}
type TaskCollection struct {
Tasks []Task `json:"items"`
}
func GetTasks(db *sql.DB) TaskCollection {
sql := "SELECT * FROM tasks"
rows, err := db.Query(sql)
// Exit jika terjadi error
if err != nil {
panic(err)
}
// clean rows
defer rows.Close()
result := TaskCollection{}
for rows.Next() {
task := Task{}
err2 := rows.Scan(&task.ID, &task.Name, &task.Status)
// Exit jika error
if err2 != nil {
panic(err2)
}
result.Tasks = append(result.Tasks, task)
}
return result
}
func PutTask(db *sql.DB, name string, status int) (int64, error) {
sql := "INSERT INTO tasks(name, status) VALUES(?,?)"
// membuat prepared SQL statement
stmt, err := db.Prepare(sql)
// Exit jika error
if err != nil {
panic(err)
}
// memastikan statement ditutup setelah selesai
defer stmt.Close()
result, err2 := stmt.Exec(name, status)
// Exit jika error
if err2 != nil {
panic(err2)
}
return result.LastInsertId()
}
func EditTask(db *sql.DB, taskId int, name string, status int) (int64, error) {
sql := "UPDATE tasks set name = ?, status = ? WHERE id = ?"
stmt, err := db.Prepare(sql)
if err != nil {
panic(err)
}
result, err2 := stmt.Exec(name, status, taskId)
if err2 != nil {
panic(err2)
}
return result.RowsAffected()
}
func DeleteTask(db *sql.DB, id int) (int64, error) {
sql := "DELETE FROM tasks WHERE id = ?"
// buat prepare statement
stmt, err := db.Prepare(sql)
// Exit jika error
if err != nil {
panic(err)
}
result, err2 := stmt.Exec(id)
// Exit jika error
if err2 != nil {
panic(err2)
}
return result.RowsAffected()
}
untuk handlersnya
package handlers
import (
"database/sql"
"net/http"
"simpleapi/models"
"strconv"
"github.com/labstack/echo"
)
type H map[string]interface{}
func GetTasks(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
return c.JSON(http.StatusOK, models.GetTasks(db))
}
}
func PutTask(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
var task models.Task
c.Bind(&task)
id, err := models.PutTask(db, task.Name, task.Status)
if err == nil {
return c.JSON(http.StatusCreated, H{
"created": id,
})
} else {
return err
}
}
}
func EditTask(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
var task models.Task
c.Bind(&task)
_, err := models.EditTask(db, task.ID, task.Name, task.Status)
if err == nil {
return c.JSON(http.StatusOK, H{
"updated": task,
})
} else {
return err
}
}
}
func DeleteTask(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
id, _ := strconv.Atoi(c.Param("id"))
_, err := models.DeleteTask(db, id)
if err == nil {
return c.JSON(http.StatusOK, H{
"deleted": id,
})
} else {
return err
}
}
}
struktur aplikasinya akan seperti berikut ini
untuk menjalankannya bisa menggunakan perintah
go run app.go
untuk testing fungsionalitas bisa menggunakan postman ataupun curl
Tes api GET untuk Read
Tes api POST untuk Create
Tes api PUT untuk Update
Tes api DELETE untuk Delete
untuk repo nya bisa dicek di link
Leave a Comment