סיכום – מודלים של REST API
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 78 מתוך 107.
אתגר
קלבואו נבנה מערכת מודלים של REST API עבור פלטפורמת בלוגים! תיצרו טיפוסים מובְנים היטב שמבצעים סריאליזציה ל-JSON ומספקים ייצוגי מחרוזת קריאים — בדיוק מה שצריך כשבונים תגובות API אמיתיות.
תארגנו את הקוד בשני קבצים:
models.go: הגדירו את מודלי הנתונים של ה-API עם תגיות JSON מתאימות וייצוגי מחרוזת.צרו מבנה
Authorעם השדותID(int),Name(string) ו-Email(string). מַפּו את השדות למפתחות JSON"id","name"ו-"email". ממשו אתString()כך שתחזיר את התבנית[Name] <[Email]>.צרו מבנה
Postעם השדותID(int),Title(string),Content(string),Author(מבנה Author מקונן) ו-Published(bool). מַפּו אותם ל-"id","title","content","author"ו-"published". השדהContentצריך להשתמש ב-omitempty, כדי שתוכן ריק לא יופיע ב-JSON. ממשו אתString()כך שתחזיר"[Title]" by [Author's String representation].צרו מבנה
APIResponseעם השדותSuccess(bool),Message(string) ו-Data(Post). מַפּו אותם ל-"success","message"ו-"data". השדהMessageצריך להשתמש ב-omitempty.main.go: בנו תגובות API והדגימו גם פלט JSON וגם ייצוגי מחרוזת.קראו סוג פעולה (
jsonאוdisplay), ולאחר מכן קראו את פרטי הפוסט: מזהה הפוסט, הכותרת, התוכן, מזהה המחבר, שם המחבר, כתובת האימייל של המחבר ומצב הפרסום (trueאוfalse).עבור
json: צרו APIResponse עםSuccess: trueואת ה-Post בתור data (השאירו את Message ריק). המרִו ל-JSON והדפיסו אותו.עבור
display: צרו את ה-Post והדפיסו אותו באמצעות שיטת String שלו, ואז הדפיסו את ה-Author בנפרד בשורה חדשה.
הקלטים הבאים יסופקו:
- שורה 1: סוג הפעולה (
jsonאוdisplay) - שורה 2: מזהה הפוסט
- שורה 3: כותרת
- שורה 4: תוכן (יכול להיות ריק)
- שורה 5: מזהה המחבר
- שורה 6: שם המחבר
- שורה 7: כתובת האימייל של המחבר
- שורה 8: מצב הפרסום (
trueאוfalse)
לדוגמה, בהינתן:
json
1
Getting Started with Go
Learn the basics of Go programming
101
Jane Smith
jane@example.com
trueהפלט שלכם צריך להיות:
{"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}}ובהינתן:
json
2
Draft Post
102
John Doe
john@example.com
falseהפלט שלכם צריך להיות:
{"success":true,"data":{"id":2,"title":"Draft Post","author":{"id":102,"name":"John Doe","email":"john@example.com"},"published":false}}שימו לב ששדה התוכן הריק מושמט מפלט ה-JSON.
ובהינתן:
display
3
Advanced Interfaces
Deep dive into Go interfaces
103
Alice Chen
alice@example.com
trueהפלט שלכם צריך להיות:
"Advanced Interfaces" by Alice Chen <alice@example.com>
Alice Chen <alice@example.com>נסו בעצמכם
package main
import (
"bufio"
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// קרא את סוג הפעולה
operation, _ := reader.ReadString('\n')
operation = strings.TrimSpace(operation)
// קרא את מזהה הפוסט
postIDStr, _ := reader.ReadString('\n')
postID, _ := strconv.Atoi(strings.TrimSpace(postIDStr))
// קרא את הכותרת
title, _ := reader.ReadString('\n')
title = strings.TrimSpace(title)
// קרא את התוכן
content, _ := reader.ReadString('\n')
content = strings.TrimSpace(content)
// קרא את מזהה המחבר
authorIDStr, _ := reader.ReadString('\n')
authorID, _ := strconv.Atoi(strings.TrimSpace(authorIDStr))
// קרא את שם המחבר
authorName, _ := reader.ReadString('\n')
authorName = strings.TrimSpace(authorName)
// קרא את כתובת האימייל של המחבר
authorEmail, _ := reader.ReadString('\n')
authorEmail = strings.TrimSpace(authorEmail)
// קרא את סטטוס הפרסום
publishedStr, _ := reader.ReadString('\n')
published := strings.TrimSpace(publishedStr) == "true"
// TODO: צור struct מסוג Author עם הערכים שנקראו
// TODO: צור struct מסוג Post עם הערכים שנקראו ועם ה-Author
// TODO: טפל בסוג הפעולה
// אם operation הוא "json":
// - צור APIResponse עם Success: true ועם Post בתור Data
// - המר ל-JSON באמצעות json.Marshal
// - הדפס את מחרוזת ה-JSON
// אם operation הוא "display":
// - הדפס את Post באמצעות המתודה String שלו
// - הדפס את Author בשורה חדשה
// קוד זמני לשימוש במשתנים (יש להסיר בעת המימוש)
_ = postID
_ = title
_ = content
_ = authorID
_ = authorName
_ = authorEmail
_ = published
_ = operation
_ = json.Marshal
fmt.Println("TODO: Implement the solution")
}
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין