مرحبا، أيها الزائر! كثيرون تساءلوا كيف تعمل ورقة مهمة بسيطة أو تطبيقات التي توفر هذه الوظائف. في هذه المقالة، أدعوكم للنظر في كيف يمكنكم كتابة خدمة صغيرة بلغو في ساعتين ووضع كل شيء في قاعدة بيانات.
دعونا نبدأ رحلتنا مع لغة جولانگ ومونغو دب.
لماذا لغة جولانگ؟
أريد أن أريكم المفاتيح:
- تصميم صغير وتجميل سريع
- نموذج للتنقل قوي مع الجوروتين والقنوات
- هيكل كبير للبيئة
- متقاطع للأجهزة من الصندوق
ويوجد عامل آخر هو تخفيف وقت مراجعة المكتبات أو الحلول المفتوحة المصدر. في حالتي، أريد إنشاء خدمة مايكروسرفت ستعمل تقريبًا من الصندوق. توفر لغة جولانگ كل ما يحتاجه لذلك.
ولكني سألاحظ أن لغة التي غنية بمشاريع جميلة تحلل الكثير من المشاكل للمطور. مثل المشاريع التالية:
- جين: 架站高效率HTTP网络框架
- فايبر: 解决方案配置(JSON、属性、YML文件)用于Go应用程序
- جورم: 关系型数据库
- بروتوكولات الإتصال (بروتوكولات): أفضل طريقة لتسيير البيانات المنظمة.
نحن لن ننظر فيهم خلف إطار المقالة، لكن ربما سأكتب شيئًا عنهم في وقت لاحق. مع Protobuf قد كتبت بالفعل مقالة مثيرة للإهتمام، “From JSON to FlatBuffers: Enhancing Performance in Data Serialization.”
التثبيت
تثبيت اللغة المستخدمة Go
أزور golang.org وتحميل. بعدها، اذهب إلى المستودع واختبره.
go version
المحرر التطبيقي
قم فقط بتثبيت VS Code (هو مجاني).
ومن ثم أضف تمديد اللغة Go:
أكتب أول برنامجك:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
ثم تشغيله:
go run main.go
هذا كل شيء! الخطوة التالية هي إختيار أفضل خيار لجمع بياناتنا.
بنية مهمتنا
أظن أن أول بنية يجب أن تكون بسيطة جدًا. دعونا نبدأ بثلاث مجالات:
- العنوان (النص)
- الوصف (النص)
- الحالة (خاص)
الملف الJSON كمرجع:
{
"title": "Go to the groceries",
"description": "Purchase milk, eggs, and bread",
"completed": false
}
لماذا MongoDB؟
نحن بحاجة إلى جمع البيانات لمهامنا وإلى مرونة. لا نحتاج إلى خلق شبكة أو علاقة بين أشياء.
- الشبكة المرنة
- التنمية: يدعم التنمية الأفقية.
- لغة التحقق الغنية
لخدمتنا الصغيرة، يمكننا أن نجريها بواسطة docker-compose
.
# استخدم root/example كمعلومات المستخدم/كلمة المرور
version: '3.1'
services:
mongo:
image: mongo
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
أفضل لي واجهة Compass GUI للعمل مع بياناتنا (المجموعات، القواعد البيانية وهلم جرا). تحميلها هنا.
قم بتشغيلها وتعيين بياناتك في “الخيارات المتقدمة“. يعمل جيدًا ويمكنه مساعدتك على إيجاد المشاكل وتحسين ال solicitudes إذا كان ذلك ما تحتاج.
تصميم النظام (صغير جدًا)
بالنسبة لخدمتنا، بالطبع، الخيار الأفضل هو إنشاء وصفات CRUD (إنشاء، قراءة، تحديث، حذف)، شيء من هذا القبيل (بدون حذف):
http.HandleFunc("/api/v1/add", todoHandler.AddTask)
http.HandleFunc("/api/v1/get-all", todoHandler.GetAllTasks)
http.HandleFunc("/api/v1/update", todoHandler.UpdateTask)
http.HandleFunc("/api/v1/complete", todoHandler.CompleteTask)
أريد استخدام الطريقة لفصل جميع المسؤوليات بواسطة المجلدات.
- المعالج – طبقة الوصول الHTTP
- النموذج – بنيات البيانات
- الحالات التي يستخدمها – طبقات الأعمال مع الخدمة والمخزن
قد تكون ترتيب المشروع هكذا:
todo-list/
│
├── cmd/
│ └── main.go
├── pkg/
│ └── handler
│ └── add_task.go
│ └── http_handler.go
│ └── complite_task.go
│ └── get_all_task.go
│ └── update_task.go
│ └── mapper
│ └── task.go
│ └── model
│ └── task.go
│ └── usecase
│ └── task
│ └── repository
│ └── add_task.go
│ └── complite_task.go
│ └── get_all_task.go
│ └── mongo_repositiry.go
│ └── repository.go
│ └── update_task.go
│ └── service
│ └── add_task.go
│ └── complite_task.go
│ └── get_all_task.go
│ └── service.go
│ └── update_task.go
└── go.mod
وكما يمكننا رؤية ، لدينا ملف “go.mod” ، لكن ما هو هذا الملف ؟ إنه مدير مكونات أو مدير اعتمادات. يمكننا تثبيت وإضافة مكونات خارجية واستخدامها أيضًا. لمثالنا الذي نحتاجه ، نحتاج عدد قليل من الأوامر التي نستخدمها بواسطة “go mod”.
- تكوين تطبيقنا ->
go mod init todo-service
. سنبدأ بجميع الأمور؛ سينشأ المدير التعليمي ملفات وسيضفي كل ما نحتاج. - إضافة اعتماد إضافي باستخدام
go mod add "link"
.
يمكنك قراءة مزيد عن هذه الصفحة مرجع مودولات Go.
ثم، دعونا نركز على مétodo واحد فقط — إضافة مهام. للاستكشاف التالي وأمثلة الكود بالكامل، أنظر إلى مجلد GitHub تعلم Golang.
اتصال بMongoDB
بواسطة المعاملات الإثنين فقط يمكننا إنشاء اتصال:
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
بالطبع ، يتوجب أن نأخذها في خدمتنا. يرجى استخدام الأوامر:
go get "go.mongodb.org/mongo-driver/mongo"
و
go get "go.mongodb.org/mongo-driver/mongo/options"
ثم، كتابة جزء من الكود:
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// تعيين خيارات عبئ المونغوب
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(options.Credential{
Username: "root",
Password: "example",
})
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err)
}
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
log.Println("Connected to MongoDB!")
}
تنظيمات لتطبيقنا:
package model
import "go.mongodb.org/mongo-driver/bson/primitive"
type Task struct {
ID string `json:"id"`
Title string `json:"title"`
Desciption string `json:"description"`
Completed bool `json:"completed"`
}
type MongoTask struct {
ID primitive.ObjectID `json:"id" bson:"_id"`
Title string `json:"title"`
Desciption string `json:"description"`
Completed bool `json:"completed"`
}
مهمة
– لل solicitud HTTP،MongoTask
– للطبقة المونغوبية: وإستخدام المقاطع الاثنين سهل لأنه في بعض الأحيان لا نحتاج إلى إرسال بيانات إضافية لمستخدمينا. مثلما قد يوجد حقل سري مثل اسم مستخدم يتوجب علينا إخفاءه.
1. طبقة المخزون:
type Repository interface {
AddTask(ctx context.Context, task model.MongoTask) error
}
func (r *MongoRepository) AddTask(ctx context.Context, task model.MongoTask) error {
task.ID = primitive.NewObjectID()
_, err := r.collection.InsertOne(ctx, task)
}
2. طبقة الخدمة:
type TodoService interface {
AddTask(ctx context.Context, task model.Task) error
}
func (s *Service) AddTask(ctx context.Context, task model.Task) error {
return s.Repo.AddTask(ctx, mapper.MapToDto(task))
}
3. طبقة المعالج (لمعالجة ال solicitudes HTTP):
func (h *Handler) AddTask(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
var task model.Task
err := json.NewDecoder(r.Body).Decode(&task)
if err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
err = h.Service.AddTask(ctx, task)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
}
وحالياً ، يتوجب علينا تنصيب اتصال القاعدة البياناتية وتكوين ال “طبقات” الاحتياجية في الملف main.go
.
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// تعيين خيارات موكل ال MongoDB
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(options.Credential{
Username: "root",
Password: "example",
})
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err)
}
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
log.Println("Connected to MongoDB!")
// تكوين المخزون والخدمة والمعالج
todoRepo := repository.NewMongoRepository(client)
todoService := service.NewService(todoRepo)
todoHandler := handler.NewHandler(todoService)
// تكوين المسارات
http.HandleFunc("/api/v1/add", todoHandler.AddTask)
// إنشاء مخزن
srv := &http.Server{
Addr: ":8080",
Handler: nil,
}
// لاحظ: تشغيل الخدمة وإيقاف
}
ونقوم باختبارها مع ال solicitud:
# curl -X POST http://localhost:8080/add
#-H "Content-Type: application/json"
#-d '{
# "id": 1,
# "title": "شراء المواد الخام",
# "completed": false
#}'
POST http://localhost:8080/api/v1/add
Content-Type: application/json
{
"title": "Add description to the structure",
"description": "your desc here..."
}
‘ That’s all. ثم، يتوجب علينا إضافة وتنفيذ طرق جديدة وسيكون خدمتنا جاهزة للعمل.
نهاية المقال
لقد أنشأنا خدمة صغيرة ومرنة لإدارة المهام باستخدام Golang و MongoDB.
وكما يمكن أن نرى إذا كان علينا بناء خدمة صغيرة فإننا نقوم بها بسرعة كبيرة بدون عقبات كثيرة. في حالتي ، أود بالفعل استخدام MongoDB كقاعدة بيانات رئيسية إذ
قد تلاحظ أيضًا أنه لن يكون الأسوأ في اللغات البرمجية الأخرى. في بعض الأماكن ، إنه حتى أسرع. على سبيل المثال ، إذا استخدمت Python و FastAPI – وهنا قد أختلف معك. اللغة Golang ما زالت مبنية على الممارسات التي تمتد في اللغات البرمجية مثل C++ و Java ، حيث يوجد OOP. هذه الأشياء والأساليب تسمح لك بحفظ البرمجيات بشكل واضح ونظيف قد تكون جيدة للبدء.
للبدء ، سيكون جيدًا أن تتأكد من تلك العوامل كالأساس ، والتي ستساعدك على فهم TDD وأيضًا أساليب أخرى. سأذكر أيضًا أنه لتجنب تعبير المقال بالمعايير والنصوص بالكثير من المعايير والنصوص، تخطيت مقارنة أداء اللغات الأخرى. سأذكر أيضًا أن Golang لا تواجد مشاكل بهذا ، وبمجرد كتابة المتغير الرئيسي ، يمكنك تشغيله في thread خاصك. يمكنك بسهولة إيجاد مقارنات على الإنترنت ، بما فيها المعاينات القياسية.
للمرور والبحث التام وأمثلة البرمجيات تأتي بزيارة المخزون GitHub (الرابط قد أُرشد مسبقًا).
شكرا واتعامل بحذر!
Source:
https://dzone.com/articles/build-a-to-do-list-with-mongodb-and-golang