حسنًا، لقد قمنا بتشغيل Go API، ولكن حان الوقت لمنحها بعض الذاكرة طويلة المدى. سنقوم هذا الأسبوع بربط واجهة برمجة التطبيقات الخاصة بنا بـ PostgreSQL، حتى تتمكن من تخزين كل تلك البيانات الثمينة دون فقدانها في اللحظة التي تغلق فيها تطبيقك. ثق بي، سيشكرك المستخدمون.
PostgreSQL أو "Postgres" باختصار، هي الصفقة الحقيقية عندما يتعلق الأمر بقواعد البيانات. إليك سبب كونها قاعدة البيانات الأكثر شيوعًا:
مليئة بالميزات : سواء كنت تريد تخزين نص قديم عادي، أو JSON، أو حتى بيانات جغرافية معقدة، فإن Postgres يوفر لك كل ما تحتاجه. كما أنه يتمتع أيضًا بامتثال كامل لـ ACID (اقرأ: فهو يحافظ على بياناتك متسقة وآمنة) وخيارات استعلام رائعة كافية لجعل أي مهووس بالبيانات يبتسم.
مفتوح المصدر ومجاني : هذا صحيح - Postgres مجاني تمامًا ومفتوح المصدر. بالإضافة إلى ذلك، فهو يحتوي على مجتمع نشط يعمل على تحسينه باستمرار، لذلك لن تقلق أبدًا بشأن أن يصبح قديمًا.
المقاييس مثل المحترفين : سواء كنت تقوم بإنشاء تطبيق صغير أو خدمة مؤسسية ضخمة تستهلك البيانات، يمكن لـ Postgres التعامل معها. لقد تم تصميمه للتوسع، مع تنفيذ الاستعلام المتوازي وسحر التحسين للحفاظ على سير الأمور بسلاسة.
بنيت مثل الخزان : مع عقود من التطوير تحت حزامها، فإن Postgres متينة كالصخر. فهو يحصل على تحديثات منتظمة، ويحتوي على الكثير من ميزات الأمان، ويتم استخدامه في الإنتاج من قبل عمالقة مثل Apple وNetflix.
هل حصلت على كل ذلك؟ رائع، دعنا نربطه بواجهة برمجة التطبيقات Go الخاصة بنا ونبدأ في العمل على بعض سحر قاعدة البيانات!
إذا لم يكن لديك PostgreSQL مثبتًا بالفعل، فاحصل عليه هنا. ثم دعونا نطلق النار عليه:
psql -U postgres
CREATE DATABASE bookdb;
\c bookdb; CREATE TABLE books ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL );
الآن لديك قاعدة بيانات جديدة جاهزة للاستخدام. حان الوقت للتحدث معه!
نحن نستخدم مكتبة pgx لهذا الغرض. إنه سريع، وخفيف الوزن، وينجز المهمة.
go get github.com/jackc/pgx/v5
افتح ملف main.go وأضف هذا الكود لإعداد اتصال بقاعدة البيانات:
var db *pgxpool.Pool func connectDB() *pgxpool.Pool { url := "postgres://postgres:yourpassword@localhost:5432/bookdb" config, err := pgxpool.ParseConfig(url) if err != nil { log.Fatalf("Unable to parse DB config: %v\n", err) } dbpool, err := pgxpool.NewWithConfig(context.Background(), config) if err != nil { log.Fatalf("Unable to connect to database: %v\n", err) } return dbpool }
استبدل كلمة المرور الخاصة بك بكلمة مرور PostgreSQL الخاصة بك. تتصل هذه الوظيفة بقاعدة بيانات bookdb الخاصة بنا وترجع تجمع اتصال، وهو ما يعني في الأساس أن تطبيقنا سيحتوي على مجموعة من الاتصالات القابلة لإعادة الاستخدام والجاهزة للاستخدام. الكفاءة يا عزيزي! ?
دعونا نتأكد من تنشيط اتصال قاعدة البيانات لدينا عندما يقوم خادمنا بذلك:
func main() { db = connectDB() defer db.Close() // Initialize router and define routes here (as before) }
حسنًا، دعنا نضيف بعض الوظائف لجلب الكتب وإنشائها وإدارتها في قاعدة بياناتنا.
func getBooks(w http.ResponseWriter, r *http.Request) { rows, err := db.Query(context.Background(), "SELECT id, title, author FROM books") if err != nil { http.Error(w, "Database error", http.StatusInternalServerError) return } defer rows.Close() var books []Book for rows.Next() { var book Book err := rows.Scan(&book.ID, &book.Title, &book.Author) if err != nil { http.Error(w, "Error scanning row", http.StatusInternalServerError) return } books = append(books, book) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(books) }
func createBook(w http.ResponseWriter, r *http.Request) { var book Book err := json.NewDecoder(r.Body).Decode(&book) if err != nil { http.Error(w, "Bad request", http.StatusBadRequest) return } _, err = db.Exec(context.Background(), "INSERT INTO books (title, author) VALUES ($1, $2)", book.Title, book.Author) if err != nil { http.Error(w, "Error inserting book", http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(book) }
نريد التأكد من أن المستخدمين المصادق عليهم فقط هم من يمكنهم الوصول إلى نقاط النهاية الجديدة التي تدعم قاعدة البيانات. استخدم البرنامج الوسيط للمصادقة من الأسبوع الثاني، وستكون جاهزًا!
func main() { db = connectDB() defer db.Close() r := mux.NewRouter() r.HandleFunc("/login", login).Methods("POST") r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET") r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST") fmt.Println("Server started on port :8000") log.Fatal(http.ListenAndServe(":8000", r)) }
دعونا نختبر هذا الشيء:
curl -X POST http://localhost:8000/books -d '{"title": "1984", "author": "George Orwell"}' -H "Content-Type: application/json"
curl http://localhost:8000/books
وازدهار! لديك واجهة برمجة تطبيقات Go مع PostgreSQL، وهي جاهزة للتعامل مع بعض البيانات الحقيقية.
في المرة القادمة، سنجعل واجهة برمجة التطبيقات (API) الخاصة بنا أكثر سهولة باستخدام بعض البرامج الوسيطة المخصصة للتسجيل ومعالجة الأخطاء. ترقبوا المزيد!
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3