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ó thể clone về với đường link sau: Github

Sau khi clone về, đổi tên project thành GolangRestApi. Vào GOPATH, copy vào thư mục src:

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.

Lấy danh sách các User

Tìm kiếm một User

Cập nhật User

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

Xóa một User

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.

(https://anhlamweb.com/bai-viet-70/xay-dung-rest-api-co-ban-trong-golang)

About the Author

Ha Trung Vi

View all author's posts

Leave a Comment

Your email address will not be published. Required fields are marked *

Bài viết khác

Web Security

Khái niệm Web Security Web Security là tập hợp các nguyên tắc, biện pháp và công nghệ nhằm bảo vệ website, ứng dụng web và dữ liệu khỏi các hành vi truy cập trái phép, tấn công độc hại hoặc khai thác lỗ hổng. Nó không chỉ bao gồm việc ngăn chặn hacker, mà còn […]

Markdown

Markdown là một ngôn ngữ đánh dấu nhẹ (lightweight markup language) dùng để định dạng văn bản thuần túy (plain text), thường được sử dụng trong các tài liệu như README, bài viết blog, tài liệu hướng dẫn, và cả trong GitHub, Stack Overflow, hoặc các trình soạn thảo như VS Code, Obsidian… Markdown được […]

CSS

CSS (Cascading Style Sheets – tạm dịch: Tập tin định kiểu tầng) là ngôn ngữ dùng để mô tả cách trình bày (giao diện) của một tài liệu HTML. Nói đơn giản, CSS giúp làm đẹp trang web: chỉnh màu sắc, font chữ, bố cục, khoảng cách, hiệu ứng chuyển động, v.v. CSS được phát […]

HTML

HTML (HyperText Markup Language) là ngôn ngữ đánh dấu siêu văn bản, được dùng để xây dựng cấu trúc của một trang web. Nói cách khác, HTML cho trình duyệt biết nội dung nào sẽ hiển thị và hiển thị như thế nào (như tiêu đề, đoạn văn, hình ảnh, liên kết…). Một tài liệu […]

Browser

Browser (Web Browser, Trình duyệt web) là phần mềm trên máy tính, điện thoại hoặc thiết bị thông minh, cho phép người dùng truy cập, hiển thị và tương tác với các trang web, tài nguyên Internet. Về bản chất, trình duyệt gửi các yêu cầu (HTTP/HTTPS request) đến máy chủ web, nhận về mã […]

Tìm hiểu DNS

DNS là gì? DNS (Domain Name System) là một dịch vụ phân giải tên miền, giúp chuyển đổi các tên miền (ví dụ: www.ducphat.com) thành địa chỉ IP (ví dụ: 93.184.216.34) và ngược lại. Thay vì phải nhớ dãy số IP, chúng ta chỉ cần nhập tên miền, DNS sẽ tìm kiếm địa chỉ IP […]