কম্পিউটার

ওয়েব ডেভেলপমেন্ট ইন গো:মিডলওয়্যার, টেমপ্লেটিং, ডেটাবেস এবং এর বাইরে

এই সিরিজের পূর্ববর্তী নিবন্ধে, আমরা 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:     "abraham.freeman@hey.com",
    }

    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": "john.smith@hmail.com"}`
    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 এর সাথে বিকাশ করার সময় সাধারণ কাজগুলি মোকাবেলা করার জন্য কীভাবে এটি ব্যবহার করতে হয়।

পড়ার জন্য ধন্যবাদ, এবং খুশি কোডিং!


  1. ক্রোমের জন্য 11টি সেরা ওয়েব ডেভেলপমেন্ট এক্সটেনশন

  2. আপনার প্রথম ওয়েব স্ক্র্যাপার তৈরি করা, পার্ট 3

  3. চ্যাটবট:ওয়েব/অ্যাপ ডেভেলপমেন্টের ভবিষ্যৎ

  4. ব্লুফিশ এবং কমপোজার দিয়ে ওয়েব ডেভেলপমেন্ট সহজ হয়েছে