Menu
CoddyTech

Ô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.

challenge icon

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 Author với các trường ID (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 đặt String() để trả về định dạng [Name] <[Email]>.

    Tạo một cấu trúc Post với ID (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ường Content nên dùng omitempty để nội dung trống không xuất hiện trong JSON. Cài đặt String() để trả về "[Title]" by [Author's String representation].

    Tạo một cấu trúc APIResponse với Success (bool), Message (string) và Data (Post). Ánh xạ các trường sang "success", "message" và "data". Trường Message nên dùng omitempty.

  • 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 (json hoặc display), 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 (true hoặc false).

    Với json: Tạo một APIResponse với Success: true và 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 (json hoặc display)
  • 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 (true hoặc false)

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

Tự luyện tập: Trình biên dịch Go online