Ôn tập: mô hình REST API
Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 78 trên 107.
Thử thách
DễHãy xây dựng hệ thống mô hình REST API cho một nền tảng blog! Bạn sẽ tạo các kiểu dữ liệu có cấu trúc tốt, có thể tuần tự hóa thành JSON và cung cấp biểu diễn chuỗi dễ đọc, đúng với những gì bạn cần khi tạo phản hồi API thực tế.
Bạn sẽ sắp xếp code trong hai tệp:
models.go: Định nghĩa các mô hình dữ liệu API với thẻ JSON phù hợp và biểu diễn chuỗi.Tạo một cấu trúc
Authorvới các trườngID(int),Name(string) vàEmail(string). Ánh xạ các trường này sang các khóa JSON"id","name"và"email". Cài đặtString()để trả về định dạng[Name] <[Email]>.Tạo một cấu trúc
PostvớiID(int),Title(string),Content(string),Author(cấu trúc Author lồng nhau) vàPublished(bool). Ánh xạ các trường này sang"id","title","content","author"và"published". TrườngContentnên dùngomitemptyđể nội dung trống không xuất hiện trong JSON. Cài đặtString()để trả về"[Title]" by [Author's String representation].Tạo một cấu trúc
APIResponsevớiSuccess(bool),Message(string) vàData(Post). Ánh xạ các trường sang"success","message"và"data". TrườngMessagenên dùngomitempty.main.go: Tạo phản hồi API và minh họa cả đầu ra JSON lẫn biểu diễn chuỗi.Đọc loại thao tác (
jsonhoặcdisplay), sau đó đọc thông tin bài đăng: ID bài đăng, tiêu đề, nội dung, ID tác giả, tên tác giả, email tác giả và trạng thái xuất bản (truehoặcfalse).Với
json: Tạo một APIResponse vớiSuccess: truevà bài đăng làm dữ liệu (để Message trống). Chuyển thành JSON rồi in ra.Với
display: Tạo Post rồi in ra bằng phương thức String, sau đó in riêng Author trên dòng mới.
Đầu vào sẽ có dạng sau:
- Dòng 1: Loại thao tác (
jsonhoặcdisplay) - Dòng 2: ID bài đăng
- Dòng 3: Tiêu đề
- Dòng 4: Nội dung (có thể để trống)
- Dòng 5: ID tác giả
- Dòng 6: Tên tác giả
- Dòng 7: Email tác giả
- Dòng 8: Trạng thái xuất bản (
truehoặcfalse)
Ví dụ, với đầu vào:
json
1
Getting Started with Go
Learn the basics of Go programming
101
Jane Smith
jane@example.com
trueĐầu ra sẽ là:
{"success":true,"data":{"id":1,"title":"Getting Started with Go","content":"Learn the basics of Go programming","author":{"id":101,"name":"Jane Smith","email":"jane@example.com"},"published":true}}Với đầu vào:
json
2
Draft Post
102
John Doe
john@example.com
falseĐầu ra sẽ là:
{"success":true,"data":{"id":2,"title":"Draft Post","author":{"id":102,"name":"John Doe","email":"john@example.com"},"published":false}}Lưu ý rằng trường nội dung trống sẽ bị lược bỏ khỏi đầu ra JSON.
Với đầu vào:
display
3
Advanced Interfaces
Deep dive into Go interfaces
103
Alice Chen
alice@example.com
trueĐầu ra sẽ là:
"Advanced Interfaces" by Alice Chen <alice@example.com>
Alice Chen <alice@example.com>Tự làm thử
package main
import (
"bufio"
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Đọc loại thao tác
operation, _ := reader.ReadString('\n')
operation = strings.TrimSpace(operation)
// Đọc ID bài viết
postIDStr, _ := reader.ReadString('\n')
postID, _ := strconv.Atoi(strings.TrimSpace(postIDStr))
// Đọc tiêu đề
title, _ := reader.ReadString('\n')
title = strings.TrimSpace(title)
// Đọc nội dung
content, _ := reader.ReadString('\n')
content = strings.TrimSpace(content)
// Đọc ID tác giả
authorIDStr, _ := reader.ReadString('\n')
authorID, _ := strconv.Atoi(strings.TrimSpace(authorIDStr))
// Đọc tên tác giả
authorName, _ := reader.ReadString('\n')
authorName = strings.TrimSpace(authorName)
// Đọc email tác giả
authorEmail, _ := reader.ReadString('\n')
authorEmail = strings.TrimSpace(authorEmail)
// Đọc trạng thái xuất bản
publishedStr, _ := reader.ReadString('\n')
published := strings.TrimSpace(publishedStr) == "true"
// TODO: Tạo struct Author với các giá trị đã đọc
// TODO: Tạo struct Post với các giá trị đã đọc và Author
// TODO: Xử lý loại thao tác
// Nếu operation là "json":
// - Tạo APIResponse với Success: true và Post làm Data
// - Chuyển sang JSON bằng json.Marshal
// - In ra chuỗi JSON
// Nếu operation là "display":
// - In ra Post bằng phương thức (method) String của nó
// - In ra Author trên một dòng mới
// Phần tạm để sử dụng các biến (xóa khi triển khai)
_ = postID
_ = title
_ = content
_ = authorID
_ = authorName
_ = authorEmail
_ = published
_ = operation
_ = json.Marshal
fmt.Println("TODO: Implement the solution")
}
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng OOP trong Go
Tệp bên ngoàiWorkspace và module trong GoPackage và importTên được export và không được exportGiới thiệu về OOP trong GoStruct như lớpĐịnh nghĩa phương thức cho structReceiver kiểu con trỏ và kiểu giá trịKhởi tạo structHàm khởi tạoÔn tập: máy tính đơn giản4Interface
Giới thiệu về interfaceTriển khai ngầm địnhInterface như một hợp đồngInterface rỗng (any)Khẳng định kiểuswitch kiểuKết hợp interfaceInterface Stringer và ErrorÔn tập: Máy tính hình học7Tính đóng gói
Trường được xuất và không được xuấtĐóng gói ở cấp packagePhương thức getter và setterẨn thông tin trong GoÔn tập: hồ sơ học sinh10Generics (Go 1.18 trở lên)
Giới thiệu về GenericsTham số kiểuRàng buộc kiểuStruct tổng quátGiải pháp thay thế cho phương thức tổng quátÔn tập: tập hợp tổng quát13Các mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếMẫu SingletonMẫu FactoryMẫu Abstract FactoryMẫu ObserverMẫu Strategy2Tìm hiểu chuyên sâu về kiểu dữ liệu và struct
Kiểu cơ bản và kiểu tổng hợpĐịnh nghĩa kiểu dữ liệu tùy chỉnhThẻ structStruct ẩn danhStruct lồng nhauGiá trị zero và giá trị mặc địnhÔn tập: sổ liên lạc5Ưu tiên kết hợp hơn kế thừa
Vì sao Go không có kế thừaNhập môn nhúng structTự động nâng phương thứcNhúng nhiều structNhúng và kết tậpChe khuất phương thức được nhúngÔn tập: hệ phân cấp nhân viên8Xử lý lỗi và lập trình hướng đối tượng
Giao diện errorCác kiểu lỗi tùy chỉnhBọc lỗi với fmt.ErrorfLỗi sentinelerrors.Is() và errors.As()Panic, defer và recoverÔn tập: trình phân tích tệp11Thư viện chuẩn và OOP
io.Reader và io.Writersort.Interfaceinterface fmt.Stringerencoding/json với structinterface http.HandlerÔn tập: mô hình REST API3Con trỏ và bộ nhớ
Cơ bản về con trỏ trong GoCon trỏ đến structTruyền theo giá trị và tham chiếuHàm new()Thu gom rác trong GoÔn tập: xây dựng danh sách liên kết6Đa hình trong Go
Đa hình qua interfaceĐịnh kiểu vịt trong GoQuy tắc thỏa mãn interfaceCác tập hợp đa hìnhTiêm phụ thuộcÔn tập: bộ xử lý thanh toán9Lập trình đồng thời và lập trình hướng đối tượng
Cơ bản về goroutineChannel và giao tiếpChannel có bộ đệm và không có bộ đệmCâu lệnh selectsync.Mutex và sync.RWMutexsync.WaitGroupThiết kế struct an toàn luồngÔn tập: worker poolTự luyện tập: Trình biên dịch Go online