Xây dựng REST API cơ bản trong Golang

Bài viết được sự cho phép của tác giả Võ Xuân Phong

Để tiếp cận với Golang một cách nhanh chóng hơn, chúng ta sẽ xây dựng một REST API cơ bản với Golang nhé.

Cấu trúc project

Chúng ta hãy tạo cấu trúc thư mục như hình bên dưới, project này có tên GolangRestApi các bạn có thể clone về với đường link sau: Github

  Chiến trường sinh tử phiên bản lập trình : Python vs Ruby vs Golang
  Channel trong Golang là gì? So sánh Callback function và mutex lock với channel

Sau khi clone về các bạn nhớ đổi tên project thành GolangRestApi và vào GOPATH rồi copy vào thư mục src, cách cài đặt và setup dự án Golang các bạn có thể tham khảo chi tiết tại bài viết này của mình:

https://anhlamweb.com/bai-viet-64/hoc-golang-tu-con-so-0-phan-1-cai-dat-golang-tren-linux-va-windows.html

Xây dựng REST API cơ bản trong Golang

Code Rest Api Golang

entities/user.go

Khai báo cấu trúc của một thực thể User. User sẽ có hàm ToString để xuất thông tin chi tiết của User đó ra.

package entities

import (
"fmt"
)

type User struct {
Id string `json:"id"`
Name string `json:"name"`
Password string `json:"password"`
}

func (user User) ToString() string {
return fmt.Sprintf("id: %s\nName: %s\nPassword: %s\n", user.Id, user.Name, user.Password)
}

models/userModel.go

Định nghĩa các hàm cơ bản như CreateUser, UpdateUser, FindUser, DeleteUser và GetAllUser. listUser dùng để chưa thông tin của các User, thay vì để khai báo listUser như vậy chúng ta có thể connect tới  database và thực hiện các thao tác như trên, nhưng để dễ hiểu và rõ ràng hơn thì ở bài viết này chúng ta sẽ thực hiện theo cách đơn giản này trước.

package models

import (
"GolangRestApi/entities"
"errors"
)

var (
listUser = make([]*entities.User, 0)
)

func CreateUser(user *entities.User) bool {
if user.Id != "" && user.Name != "" && user.Password != "" {
if userF, _ := FindUser(user.Id); userF == nil {
listUser = append(listUser, user)
return true
}
}
return false
}

func UpdateUser(eUser *entities.User) bool {
for index, user := range listUser {
if user.Id == eUser.Id {
listUser[index] = eUser
return true
}
}
return false
}

func FindUser(id string) (*entities.User, error) {
for _, user := range listUser {
if user.Id == id {
return user, nil
}
}
return nil, errors.New("User does not exist")
}

func DeleteUser(id string) bool {
for index, user := range listUser {
if user.Id == id {
copy(listUser[index:], listUser[index+1:])
listUser[len(listUser)-1] = &entities.User{}
listUser = listUser[:len(listUser)-1]
return true
}
}
return false
}

func GetAllUser() []*entities.User {
return listUser
}

apis/userapi/userApi.go

Ở file này là các hàm xử lý các http request và chịu trách nhiệm trả về kết quả cho người dùng bằng http response.

package userapi

import (
"GolangRestApi/entities"
"GolangRestApi/models"
"encoding/json"
"net/http"
)

func FindUser(response http.ResponseWriter, request *http.Request) {
ids, ok := request.URL.Query()["id"]
if !ok || len(ids) < 1 {
responseWithError(response, http.StatusBadRequest, "Url Param id is missing")
return
}
user, err := models.FindUser(ids[0])
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
return
}
responseWithJSON(response, http.StatusOK, user)
}

func GetAll(response http.ResponseWriter, request *http.Request) {
users := models.GetAllUser()
responseWithJSON(response, http.StatusOK, users)
}

func CreateUser(response http.ResponseWriter, request *http.Request) {
var user entities.User
err := json.NewDecoder(request.Body).Decode(&user)
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
} else {
result := models.CreateUser(&user)
if !result {
responseWithError(response, http.StatusBadRequest, "Could not create user")
return
}
responseWithJSON(response, http.StatusOK, user)
}
}

func UpdateUser(response http.ResponseWriter, request *http.Request) {
var user entities.User
err := json.NewDecoder(request.Body).Decode(&user)
if err != nil {
responseWithError(response, http.StatusBadRequest, err.Error())
} else {
result := models.UpdateUser(&user)
if !result {
responseWithError(response, http.StatusBadRequest, "Could not update user")
return
}
responseWithJSON(response, http.StatusOK, "Update user successfully")
}
}

func Delete(response http.ResponseWriter, request *http.Request) {
ids, ok := request.URL.Query()["id"]
if !ok || len(ids) < 1 {
responseWithError(response, http.StatusBadRequest, "Url Param id is missing")
return
}
result := models.DeleteUser(ids[0])
if !result {
responseWithError(response, http.StatusBadRequest, "Could not delete user")
return
}
responseWithJSON(response, http.StatusOK, "Delete user successfully")
}

func responseWithError(response http.ResponseWriter, statusCode int, msg string) {
responseWithJSON(response, statusCode, map[string]string{
"error": msg,
})
}

func responseWithJSON(response http.ResponseWriter, statusCode int, data interface{}) {
result, _ := json.Marshal(data)
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(statusCode)
response.Write(result)
}

Main.go

Để xây dựng một REST Api Server thì ở đây chúng ta sử dụng mux và tạo một router để nó thực hiện việc handle request như sau.

Server sẽ lắng nghe ở port 5000.

package main

import (
"GolangRestApi/apis/userapi"
"net/http"

"github.com/gorilla/mux"
)

func main() {
router := mux.NewRouter()

router.HandleFunc("/api/v1/user/find", userapi.FindUser).Methods("GET")
router.HandleFunc("/api/v1/user/getall", userapi.GetAll).Methods("GET")
router.HandleFunc("/api/v1/user/create", userapi.CreateUser).Methods("POST")
router.HandleFunc("/api/v1/user/update", userapi.UpdateUser).Methods("PUT")
router.HandleFunc("/api/v1/user/delete", userapi.Delete).Methods("DELETE")

err := http.ListenAndServe(":5000", router)
if err != nil {
panic(err)
}
}

Chạy chương trình bằng lệnh

go run main.go

Kiểm Tra Kết Quả

Để kiểm tra kết quả chúng ta sẽ sử dụng Postman nhé, bạn có thể vào thư mục assets và import file GolangRestApi.postman_collection.json vào để test cho nhanh.

Tạo mới User.

Xây dựng REST API cơ bản trong Golang

Lấy danh sách các User

Xây dựng REST API cơ bản trong Golang

Tìm kiếm một User

Xây dựng REST API cơ bản trong Golang

Cập nhật User

Xây dựng REST API cơ bản trong Golang

Sau khi update user chúng ta hãy kiểm tra lại thông tin vừa được update.

Xây dựng REST API cơ bản trong Golang

Xóa một User

Xây dựng REST API cơ bản trong Golang

Sau khi delete user chúng ta hãy kiểm tra lại danh sách, như hình bên dưới sau khi delete user đi thì danh sách là rỗng.

Xây dựng REST API cơ bản trong Golang

Tổng kết:

Chúng ta đã tập làm quen với Golang và Rest Api trong Golang, ở bài tiếp theo chúng ta sẽ tìm hiểu tiếp về xác thực Rest Api sử dụng Json Web Token nhé.

Bài viết gốc được đăng tải tại anhlamweb.com

Có thể bạn quan tâm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev