এই সিরিজের পূর্ববর্তী নিবন্ধে, আমরা Gonet/http
নিয়ে একটি বিস্তৃত আলোচনা করেছি প্যাকেজ এবং কীভাবে এটি উত্পাদন-প্রস্তুত ওয়েব অ্যাপ্লিকেশনগুলির জন্য ব্যবহার করা যেতে পারে৷ আমরা বেশিরভাগই http.ServeMux
-এর রাউটিং দিক এবং অন্যান্য বৈশিষ্ট্য এবং বৈশিষ্ট্যগুলিতে ফোকাস করেছি। টাইপ করুন।
এই নিবন্ধটি ServeMux
নিয়ে আলোচনা বন্ধ করবে ডিফল্ট রাউটারের সাথে হাউমিডলওয়্যার ফাংশনগুলিকে প্রদর্শন করে এবং অন্যান্য স্ট্যান্ডার্ড লাইব্রেরি প্যাকেজগুলি প্রবর্তন করা যেতে পারে যা Go-এর সাথে ওয়েব পরিষেবাগুলি বিকাশ করার সময় কাজে আসবে৷
গোতে মিডলওয়্যার
৷শেয়ার্ড কার্যকারিতা সেট আপ করার অনুশীলন যা অনেক মৌখিক HTTP অনুরোধের জন্য চালানো প্রয়োজন তাকে মিডলওয়্যার বলা হয় . কিছু ক্রিয়াকলাপ, যেমন প্রমাণীকরণ, লগিং এবং কুকি যাচাইকরণ, প্রায়শই মিডলওয়্যার ফাংশন হিসাবে প্রয়োগ করা হয়, যা নিয়মিত রুট হ্যান্ডলারের আগে বা পরে স্বাধীনভাবে একটি অনুরোধে কাজ করে।
Go-তে মিডলওয়্যার প্রয়োগ করতে, আপনাকে নিশ্চিত করতে হবে যে আপনার কাছে এমন একটি প্রকার আছে যা http.Handler ইন্টারফেসকে সন্তুষ্ট করে৷ সাধারণত, এর মানে হল যে আপনাকে স্বাক্ষর সহ একটি পদ্ধতি সংযুক্ত করতে হবেServeHTTP(http.ResponseWriter, *http.Request)
টাইপের কাছে। এই পদ্ধতি ব্যবহার করার সময়, যেকোন প্রকার http.Handler
কে সন্তুষ্ট করবে ইন্টারফেস।
এখানে একটি সহজ উদাহরণ:
package main
import "net/http"
type helloHandler struct {
name string
}
func (h helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello " + h.name))
}
func main() {
mux := http.NewServeMux()
helloJohn := helloHandler{name: "John"}
mux.Handle("/john", helloJohn)
http.ListenAndServe(":8080", mux)
}
/john
-এ পাঠানো যেকোনো অনুরোধ রুটটি সরাসরি helloHandler.ServeHTTP
-এ চলে যাবে পদ্ধতি আপনি সার্ভার শুরু করে এবং https://localhost:8080/john-এ যাওয়ার মাধ্যমে এটিকে কার্যকরভাবে পর্যবেক্ষণ করতে পারেন।
ServeHTTP
যোগ করতে হবে আপনি যখনই http.Handler
প্রয়োগ করতে চান তখন একটি কাস্টম টাইপের পদ্ধতি বেশ ক্লান্তিকর হবে, তাই net/http
প্যাকেজ http.HandlerFunc
প্রদান করে টাইপ, যা HTTP হ্যান্ডলার হিসাবে সাধারণ ফাংশন ব্যবহারের অনুমতি দেয়।
আপনাকে যা করতে হবে তা হল আপনার ফাংশনে নিম্নলিখিত স্বাক্ষর রয়েছে তা নিশ্চিত করুন:func(http.ResponseWriter, *http.Request)
; তারপর, এটিকে http.HandlerFunc
-এ রূপান্তর করুন টাইপ করুন।
package main
import "net/http"
func helloJohnHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello John"))
}
func main() {
mux := http.NewServeMux()
mux.Handle("/john", http.HandlerFunc(helloJohnHandler))
http.ListenAndServe(":8080", mux)
}
এমনকি আপনি mux.Handle
প্রতিস্থাপন করতে পারেন main
এ লাইন উপরে mux.HandleFunc
এর সাথে ফাংশন এবং সরাসরি এটিতে ফাংশনটি পাস করুন। আমরা পূর্ববর্তী নিবন্ধে এই প্যাটার্নটি একচেটিয়াভাবে ব্যবহার করেছি।
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/john", helloJohnHandler)
http.ListenAndServe(":8080", mux)
}
এই মুহুর্তে, নামটি স্ট্রিং-এ হার্ডকোড করা হয়, আগে যখন আমরা main
এ নাম সেট করতে পারতাম তার বিপরীতে হ্যান্ডলারকে কল করার আগে ফাংশন। এই সীমাবদ্ধতা দূর করে, আমরা আমাদের হ্যান্ডলার লজিককে বন্ধ করে দিতে পারি, যেমনটি নীচে দেখানো হয়েছে:
package main
import "net/http"
func helloHandler(name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello " + name))
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/john", helloHandler("John"))
http.ListenAndServe(":8080", mux)
}
helloHandler
ফাংশন নিজেই http.Handler
কে সন্তুষ্ট করে না ইন্টারফেস, কিন্তু এটি একটি বেনামী ফাংশন তৈরি করে এবং ফেরত দেয় যা করে। এই ফাংশনটি name
এর উপর বন্ধ হয়ে যায় প্যারামিটার, যার মানে এটি যখনই কল করা হয় তখন এটি অ্যাক্সেস করতে পারে। এই সময়ে, helloHandler
ফাংশন প্রয়োজনমত বিভিন্ন নামের জন্য পুনরায় ব্যবহার করা যেতে পারে।
সুতরাং, মিডলওয়্যারের সাথে এই সমস্তের কী সম্পর্ক আছে? ঠিক আছে, একটি মিডলওয়্যার ফাংশন তৈরি করা হয় যেভাবে আমরা উপরে দেখেছি। ক্লোজারে একটি স্ট্রিং পাস করার পরিবর্তে (উদাহরণ হিসাবে), আমরা একটি আর্গুমেন্ট হিসাবে চেইনের পরবর্তী হ্যান্ডলারকে পাস করতে পারি।
এখানে সম্পূর্ণ প্যাটার্ন আছে:
func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Middleware logic goes here...
next.ServeHTTP(w, r)
})
}
middleware
উপরের ফাংশন একটি হ্যান্ডলারকে গ্রহণ করে এবং একটি হ্যান্ডলার ফেরত দেয়৷ লক্ষ্য করুন কিভাবে আমরা বেনামী ফাংশনকে http.Handler
কে সন্তুষ্ট করতে সক্ষম হয়েছি। একটি http.HandlerFunc
এ কাস্ট করে ইন্টারফেস প্রকার বেনামী ফাংশনের শেষে, নিয়ন্ত্রণ next
-এ স্থানান্তরিত হয় ServeHTTP()
আহ্বান করে হ্যান্ডলার পদ্ধতি আপনি যদি হ্যান্ডলারগুলির মধ্যে মানগুলি পাস করতে চান, যেমন একটি প্রমাণীকৃত ব্যবহারকারীর আইডি, আপনি http.Request.Context()
ব্যবহার করতে পারেন Go 1.7 এ পদ্ধতি চালু করা হয়েছে।
আসুন একটি মিডলওয়্যার ফাংশন লিখি যা কেবল এই প্যাটার্নটি প্রদর্শন করে। এই ফাংশন requestTime
নামে একটি বৈশিষ্ট্য যোগ করে অনুরোধ বস্তুতে, যা পরবর্তীতে helloHandler
দ্বারা ব্যবহার করা হয়েছে একটি অনুরোধের টাইমস্ট্যাম্প প্রদর্শন করতে।
package main
import (
"context"
"net/http"
"time"
)
func requestTime(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(ctx, "requestTime", time.Now().Format(time.RFC3339))
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
func helloHandler(name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
responseText := "<h1>Hello " + name + "</h1>"
if requestTime := r.Context().Value("requestTime"); requestTime != nil {
if str, ok := requestTime.(string); ok {
responseText = responseText + "\n<small>Generated at: " + str + "</small>"
}
}
w.Write([]byte(responseText))
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/john", requestTime(helloHandler("John")))
http.ListenAndServe(":8080", mux)
}
যেহেতু আমাদের মিডলওয়্যার ফাংশন একটি http.Handler
গ্রহণ করে এবং ফেরত দেয় টাইপ করুন, একে অপরের ভিতরে নেস্টেড মিডলওয়্যার ফাংশনগুলির একটি অসীম চেইন তৈরি করা সম্ভব।
উদাহরণস্বরূপ,
mux := http.NewServeMux()
mux.Handle("/", middleware1(middleware2(appHandler)))
উপরের গঠনটিকে আরও পাঠযোগ্য ফর্মে রূপান্তর করতে আপনি অ্যালিসের মতো একটি লাইব্রেরি ব্যবহার করতে পারেন যেমন:
alice.New(middleware1, middleware2).Then(appHandler)
টেমপ্লেটিং
যদিও একক-পৃষ্ঠা অ্যাপ্লিকেশনের আবির্ভাবের সাথে টেমপ্লেটের ব্যবহার হ্রাস পেয়েছে, এটি একটি সম্পূর্ণ ওয়েব ডেভেলপমেন্ট সলিউশনের একটি গুরুত্বপূর্ণ দিক হিসেবে রয়ে গেছে।
Go আপনার সমস্ত টেমপ্লেটিং প্রয়োজনের জন্য দুটি প্যাকেজ প্রদান করে:text/template
এবংhtml/template
. তাদের উভয়েরই একই ইন্টারফেস রয়েছে, কিন্তু পরবর্তীটি কোড ইনজেকশনের অপব্যবহার থেকে রক্ষা করার জন্য পর্দার আড়ালে কিছু এনকোডিং করবে৷
যদিও Go টেমপ্লেটগুলি সেখানে সবচেয়ে অভিব্যক্তিপূর্ণ নয়, তারা কাজটি ঠিকঠাক করে ফেলে এবং উত্পাদন অ্যাপ্লিকেশনের জন্য ব্যবহার করা যেতে পারে। প্রকৃতপক্ষে, এটিই হুগো, জনপ্রিয় স্ট্যাটিক সাইট জেনারেটর, এটির টেমপ্লেটিং সিস্টেমকে ভিত্তি করে৷
চলুন কিভাবে html/template
তা দ্রুত দেখে নেওয়া যাক একটি ওয়েব অনুরোধের প্রতিক্রিয়া হিসাবে HTML আউটপুট পাঠাতে প্যাকেজ ব্যবহার করা যেতে পারে৷
একটি টেমপ্লেট তৈরি করা
একটি index.html
তৈরি করুন আপনার main.go
একই ডিরেক্টরিতে ফাইল করুন ফাইল এবং ফাইলে নিম্নলিখিত কোড যোগ করুন:
<ul>
{{ range .TodoItems }}
<li>{{ . }}</li>
{{ end }}
</ul>
এরপর, আপনার main.go
-এ নিম্নলিখিত কোডটি যোগ করুন ফাইল:
package main
import (
"html/template"
"log"
"os"
)
func main() {
t, err := template.ParseFiles("index.html")
if err != nil {
log.Fatal(err)
}
todos := []string{"Watch TV", "Do homework", "Play games", "Read"}
err = t.Execute(os.Stdout, todos)
if err != nil {
log.Fatal(err)
}
}
আপনি যদি উপরের প্রোগ্রামটি go run main.go
দিয়ে চালান . আপনি নিম্নলিখিত আউটপুট দেখতে হবে:
<ul>
<li>Watch TV</li>
<li>Do homework</li>
<li>Play games</li>
<li>Read</li>
</ul>
অভিনন্দন! আপনি এইমাত্র আপনার প্রথম Go টেমপ্লেট তৈরি করেছেন৷ টেমপ্লেট ফাইলে আমরা যে সিনট্যাক্স ব্যবহার করেছি তার একটি সংক্ষিপ্ত ব্যাখ্যা এখানে:
- গো ডাবল ব্রেস ব্যবহার করে (
{{
) এবং}}
) ডেটা মূল্যায়ন এবং নিয়ন্ত্রণ কাঠামো সীমাবদ্ধ করতে (যা ক্রিয়া নামে পরিচিত ) টেমপ্লেটে। -
range
কর্ম হল কিভাবে আমরা ডাটা স্ট্রাকচারের উপর পুনরাবৃত্তি করতে পারি, যেমন স্লাইস। .
বর্তমান প্রেক্ষাপট প্রতিনিধিত্ব করে।range
কর্ম, বর্তমান প্রসঙ্গ হলtodos
এর স্লাইস . ব্লকের ভিতরে,{{ . }}
স্লাইসের প্রতিটি উপাদানকে বোঝায়।
main.go
-এ ফাইল, template.ParseFiles
পদ্ধতি এক বা একাধিক ফাইল থেকে একটি নতুন টেমপ্লেট তৈরি করতে ব্যবহৃত হয়। এই টেমপ্লেটটি পরবর্তীতে template.Execute
ব্যবহার করে কার্যকর করা হয় পদ্ধতি এটি একটি io.Writer
লাগে এবং ডেটা, যা টেমপ্লেটে প্রয়োগ করা হবে।
উপরের উদাহরণে, টেমপ্লেটটি স্ট্যান্ডার্ড আউটপুটে কার্যকর করা হয়, তবে আমরা এটিকে যে কোনো গন্তব্যে চালাতে পারি, যতক্ষণ না এটি io.Writer
-কে সন্তুষ্ট করে। ইন্টারফেস. উদাহরণস্বরূপ, যদি আপনি একটি ওয়েবরিকোয়েস্টের অংশ হিসাবে আউটপুটটি ফেরত দিতে চান, তাহলে আপনাকে যা করতে হবে তা হল ResponseWriter
-এ টেমপ্লেটটি চালান। ইন্টারফেস, নীচে দেখানো হিসাবে।
package main
import (
"html/template"
"log"
"net/http"
)
func main() {
t, err := template.ParseFiles("index.html")
if err != nil {
log.Fatal(err)
}
todos := []string{"Watch TV", "Do homework", "Play games", "Read"}
http.HandleFunc("/todos", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
err = t.Execute(w, todos)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
http.ListenAndServe(":8080", nil)
}
এই বিভাগটি শুধুমাত্র Go-এর টেমপ্লেট প্যাকেজগুলির একটি দ্রুত ভূমিকার জন্য বোঝানো হয়েছে। আপনি যদি আরও জটিল ব্যবহারের ক্ষেত্রে আগ্রহী হন তবে পাঠ্য/টেমপ্লেট এবং এইচটিএমএল/টেমপ্লেটের জন্য ডকুমেন্টেশন পরীক্ষা করে দেখুন৷
আপনি যদি গো কীভাবে এর টেমপ্লেটিং করে তার অনুরাগী না হন, তাহলে প্লাস লাইব্রেরির মতো বিকল্প রয়েছে।
JSON এর সাথে কাজ করা
আপনার যদি JSON অবজেক্টের সাথে কাজ করার প্রয়োজন হয়, তাহলে আপনি শুনে খুশি হবেন যে Go-এর স্ট্যান্ডার্ড লাইব্রেরিতে আপনাকে encoding/json
এর মাধ্যমে JSON পার্স এবং এনকোড করার জন্য প্রয়োজনীয় সবকিছু অন্তর্ভুক্ত করে প্যাকেজ।
ডিফল্ট প্রকার
Go-তে JSON অবজেক্ট এনকোডিং বা ডিকোড করার সময়, নিম্নলিখিত প্রকারগুলি ব্যবহার করা হয়:
bool
JSON বুলিয়ানের জন্য,float64
JSON নম্বরের জন্য,string
JSON স্ট্রিংগুলির জন্য,nil
JSON নাল এর জন্য,map[string]interface{}
JSON বস্তুর জন্য, এবং[]interface{}
JSON অ্যারেগুলির জন্য৷
৷
এনকোডিং
JSON হিসাবে একটি ডেটা স্ট্রাকচার এনকোড করতে, json.Marshal
ফাংশন ব্যবহার করা হয়। এখানে একটি উদাহরণ:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string
LastName string
Age int
email string
}
func main() {
p := Person{
FirstName: "Abraham",
LastName: "Freeman",
Age: 100,
email: "[email protected]",
}
json, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(json))
}
উপরের প্রোগ্রামে, আমাদের একটি Person
আছে চারটি ভিন্ন ক্ষেত্র সহ struct। main
-এ ফাংশন, Person
এর একটি উদাহরণ সমস্ত ক্ষেত্র চালু করে তৈরি করা হয়। json.Marshal
পদ্ধতিটি তারপর p
রূপান্তর করতে ব্যবহৃত হয় JSON এর কাঠামো। এই পদ্ধতিটি বাইটের একটি স্লাইস বা একটি ত্রুটি প্রদান করে, যা আমাদের JSON ডেটা অ্যাক্সেস করার আগে পরিচালনা করতে হবে।
বাইটের একটি স্লাইসকে গো-তে একটি স্ট্রিংয়ে রূপান্তর করতে, আমাদের টাইপ কনভার্সন করতে হবে, যেমনটি উপরে দেখানো হয়েছে। এই প্রোগ্রামটি চালানোর ফলে নিম্নলিখিত আউটপুট তৈরি হবে:
{"FirstName":"Abraham","LastName":"Freeman","Age":100}
আপনি দেখতে পাচ্ছেন, আমরা একটি বৈধ JSON অবজেক্ট পেয়েছি যা আমাদের ইচ্ছামত ব্যবহার করা যেতে পারে। মনে রাখবেন যে email
ক্ষেত্রটি ফলাফলের বাইরে থাকে। কারণ এটি Person
থেকে রপ্তানি হয় না ছোট হাতের অক্ষর দিয়ে শুরু করার কারণে বস্তু।
ডিফল্টরূপে, গো স্ট্রাকটে একই সম্পত্তির নাম ব্যবহার করে যার ফলস্বরূপ JSON অবজেক্টের ক্ষেত্রের নাম। যাইহোক, এটি স্ট্রাকফিল্ড ট্যাগ ব্যবহারের মাধ্যমে পরিবর্তন করা যেতে পারে।
type Person struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Age int `json:"age"`
email string `json:"email"`
}
উপরের struct ফিল্ড ট্যাগগুলি নির্দিষ্ট করে যে JSON এনকোডারকে FirstName
ম্যাপ করা উচিত first_name
-এর struct-এ সম্পত্তি JSON অবজেক্টে ক্ষেত্র এবং তাই। পূর্ববর্তী উদাহরণে এই পরিবর্তনটি নিম্নলিখিত আউটপুট তৈরি করে:
{"first_name":"Abraham","last_name":"Freeman","age":100}
ডিকোডিং
json.Unmarshal
ফাংশন একটি Gostruct মধ্যে একটি JSON অবজেক্ট ডিকোড করার জন্য ব্যবহার করা হয়. এটিতে নিম্নলিখিত স্বাক্ষর রয়েছে:
func Unmarshal(data []byte, v interface{}) error
এটি JSON ডেটার একটি বাইট স্লাইস এবং ডিকোড করা ডেটা সঞ্চয় করার জায়গা গ্রহণ করে। যদি ডিকোডিং সফল হয়, তাহলে ফেরত ত্রুটি nil
হবে .
ধরে নিচ্ছি আমাদের নিম্নলিখিত JSON অবজেক্ট আছে,
json := "{"first_name":"John","last_name":"Smith","age":35, "place_of_birth": "London", gender:"male"}"
আমরা এটিকে Person
এর উদাহরণে ডিকোড করতে পারি struct, নীচে দেখানো হিসাবে:
func main() {
b := `{"first_name":"John","last_name":"Smith","age":35, "place_of_birth": "London", "gender":"male", "email": "[email protected]"}`
var p Person
err := json.Unmarshal([]byte(b), &p)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v\n", p)
}
এবং আপনি নিম্নলিখিত আউটপুট পাবেন:
{FirstName:John LastName:Smith Age:35 email:}
Unmarshal
শুধুমাত্র গন্তব্যের ধরনে পাওয়া ক্ষেত্রগুলিকে ডিকোড করে। এই ক্ষেত্রে, place_of_birth
এবং gender
উপেক্ষা করা হয় কারণ তারা Person
-এ কোনো struct ফিল্ড ম্যাপ করে না . একটি বড় JSON অবজেক্ট থেকে শুধুমাত্র কয়েকটি নির্দিষ্ট ক্ষেত্র বাছাই করতে এই আচরণটি ব্যবহার করা যেতে পারে। আগের মতই, JSON অবজেক্টে একটি সংশ্লিষ্ট ক্ষেত্র থাকলেও গন্তব্যের কাঠামোতে রপ্তানি না করা ক্ষেত্রগুলি প্রভাবিত হয় না। এই কারণেই email
আউটপুটে একটি খালি স্ট্রিং থাকে যদিও এটি JSON অবজেক্টে উপস্থিত থাকে।
ডেটাবেস
database/sql
প্যাকেজ এসকিউএল (বা এসকিউএল-এর মতো) ডাটাবেসের চারপাশে একটি জেনেরিক ইন্টারফেস প্রদান করে। এটি একটি ডাটাবেস ড্রাইভারের সাথে ব্যবহার করা আবশ্যক, যেমন এখানে তালিকাভুক্ত থিওনগুলি। ডাটাবেস ড্রাইভার ইম্পোর্ট করার সময়, আপনাকে একটি আন্ডারস্কোর _
দিয়ে এটির উপসর্গ দিতে হবে শুরু করতে।
উদাহরণস্বরূপ, database/sql
এর সাথে MySQLdriver প্যাকেজটি কীভাবে ব্যবহার করবেন তা এখানে রয়েছে :
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
হুডের নিচে, ড্রাইভার নিজেকে database/sql
-এ উপলব্ধ বলে নিবন্ধন করে প্যাকেজ, কিন্তু এটি সরাসরি আমাদের কোডে ব্যবহার করা হবে না। এটি একটি নির্দিষ্ট ড্রাইভারের উপর নির্ভরতা কমাতে সাহায্য করে যাতে এটিকে ন্যূনতম প্রচেষ্টায় সহজেই অন্যের জন্য অদলবদল করা যায়।
একটি ডাটাবেস সংযোগ খোলা
একটি ডাটাবেস অ্যাক্সেস করতে, আপনাকে একটি sql.DB
তৈরি করতে হবে অবজেক্ট, নীচে দেখানো হিসাবে:
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
}
sql.Open
পদ্ধতি পরবর্তী ব্যবহারের জন্য ডাটাবেস বিমূর্ততা প্রস্তুত করে। এটি ডাটাবেসের সাথে একটি সংযোগ স্থাপন করে না বা সংযোগের পরামিতিগুলিকে বৈধ করে না। আপনি যদি নিশ্চিত করতে চান যে ডাটাবেসটি উপলব্ধ এবং অবিলম্বে অ্যাক্সেসযোগ্য, তাহলে db.Ping()
ব্যবহার করুন পদ্ধতি:
err = db.Ping()
if err != nil {
log.Fatal(err)
}
একটি ডাটাবেস সংযোগ বন্ধ করা
একটি ডাটাবেস সংযোগ বন্ধ করতে, আপনি db.Close()
ব্যবহার করতে পারেন . সাধারণত, আপনি defer
করতে চান ডাটাবেস বন্ধ হওয়া পর্যন্ত যে ফাংশনটি ডাটাবেস সংযোগটি খুলেছে সেটি শেষ না হওয়া পর্যন্ত, সাধারণত main
ফাংশন:
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
sql.DB
বস্তুটি দীর্ঘস্থায়ী হওয়ার জন্য ডিজাইন করা হয়েছে, তাই আপনার এটি ঘন ঘন খোলা বা বন্ধ করা উচিত নয়। যদি আপনি তা করেন, আপনি সমস্যাগুলি অনুভব করতে পারেন, যেমন দুর্বল পুনঃব্যবহার এবং সংযোগগুলি ভাগ করে নেওয়া, উপলব্ধ নেটওয়ার্ক সংস্থানগুলি ফুরিয়ে যাওয়া, বা স্পোরাডিক ব্যর্থতা৷ sql.DB
পাস করা ভাল পদ্ধতির আশেপাশে বা এটিকে বিশ্বব্যাপী উপলভ্য করুন এবং শুধুমাত্র সেই ডেটাস্টোরে প্রবেশ করার প্রোগ্রামটি সম্পন্ন হলেই এটি বন্ধ করুন৷
ডাটাবেস থেকে ডেটা আনা হচ্ছে
একটি টেবিলের অনুসন্ধান তিনটি ধাপে করা যেতে পারে। প্রথমে db.Query()
কল করুন . তারপর, সারি উপর পুনরাবৃত্তি. অবশেষে, rows.Scan()
ব্যবহার করুন প্রতিটি সারি ইনভেরিয়েবল বের করতে। এখানে একটি উদাহরণ:
var (
id int
name string
)
rows, err := db.Query("select id, name from users where id = ?", 1)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
log.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
যদি একটি প্রশ্ন একটি একক সারি প্রদান করে, আপনি db.QueryRow
ব্যবহার করতে পারেন db.Query
এর পরিবর্তে পদ্ধতি এবং পূর্ববর্তী কোডস্নিপেটে কিছু লম্বা বয়লারপ্লেট কোড এড়িয়ে চলুন:
var (
id int
name string
)
err = db.QueryRow("select id, name from users where id = ?", 1).Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
fmt.Println(id, name)
NoSQL ডেটাবেস
Go এও NoSQL ডাটাবেসগুলির জন্য ভাল সমর্থন রয়েছে, যেমন Redis, MongoDB, Cassandra, এবং এর মতো, কিন্তু এটি তাদের সাথে কাজ করার জন্য একটি আদর্শ ইন্টারফেস প্রদান করে না। নির্দিষ্ট ডেটাবেসের জন্য আপনাকে সম্পূর্ণরূপে ড্রাইভার প্যাকেজের উপর নির্ভর করতে হবে। কিছু উদাহরণ নীচে তালিকাভুক্ত করা হয়েছে৷
৷- https://github.com/go-redis/redis (Redis ড্রাইভার)।
- https://github.com/mongodb/mongo-go-driver (MongoDB ড্রাইভার)।
- https://github.com/gocql/gocql (ক্যাসান্দ্রা ড্রাইভার)।
- https://github.com/Shopify/sarama (Apache Kafka ড্রাইভার)
র্যাপিং আপ
এই নিবন্ধে, আমরা Go এর সাথে ওয়েব অ্যাপ্লিকেশন তৈরি করার কিছু প্রয়োজনীয় দিক নিয়ে আলোচনা করেছি। আপনি এখন বুঝতে সক্ষম হবেন কেন অনেক গোপ্রোগ্রামার স্ট্যান্ডার্ড লাইব্রেরি দ্বারা শপথ করেন। এটি অত্যন্ত ব্যাপক এবং একটি উৎপাদন-প্রস্তুত পরিষেবার জন্য প্রয়োজনীয় বেশিরভাগ সরঞ্জাম সরবরাহ করে৷
আমরা এখানে কভার করেছি এমন কিছু সম্পর্কে আপনার যদি স্পষ্টীকরণের প্রয়োজন হয়, অনুগ্রহ করে আমাকে টুইটারে বার্তা পাঠান। এই সিরিজের পরবর্তী এবং চূড়ান্ত নিবন্ধে, আমরা go
নিয়ে আলোচনা করব টুল এবং Go এর সাথে বিকাশ করার সময় সাধারণ কাজগুলি মোকাবেলা করার জন্য কীভাবে এটি ব্যবহার করতে হয়।
পড়ার জন্য ধন্যবাদ, এবং খুশি কোডিং!