Server de web in golang cu sesiuni si POST date in JSON

Categorii: Programare, Internet

14-Apr-2022 15:48 - 534 vizionari

Un exemplu de server in golang apelat cu functii JavaScript descrise in JS Promises, Fetch and Arrow Functions.


package main

import (
	"embed"
	"encoding/json"
	"fmt"
	"html/template"
	"net/http"
	"time"

	"github.com/braintree/manners"
	"github.com/gorilla/mux"
	"github.com/gorilla/sessions"
)

//go:embed static
var static_fs embed.FS

//go:embed templates
var tpl_fs embed.FS
var tpl, _ = template.ParseFS(tpl_fs, "templates/*.tmpl") // ignor eroarea

// key must be 16, 24 or 32 bytes long (AES-128, AES-192 or AES-256)
var key = make([]byte, 16)
var store *sessions.CookieStore

const session_cookie_name = "gowebsession"

type dict map[string]interface{}

func main() {
	fmt.Println("Start app.")

	r := mux.NewRouter()
	store = sessions.NewCookieStore(key)

	r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		const time_format = "02/Jan/2006 15:04:05"
		// now := time.Unix(time.Now().Unix(), 0).Format((time_format))
		now := time.Now().Format((time_format))

		// get session, update, then save
		session, _ := store.Get(r, session_cookie_name)
		if session.Values["cnt"] == nil {
			session.Values["cnt"] = 0
		}
		session.Values["cnt"] = session.Values["cnt"].(int) + 1
		session.Values["now"] = now
		session.Save(r, w)

		fmt.Printf("index session values = %v\n", session.Values)
		title := "go App with Webserver"
		data := dict{
			"title": title,
		}
		tpl.ExecuteTemplate(w, "index", data)
	})

	r.HandleFunc("/x", func(w http.ResponseWriter, r *http.Request) {
		// oprire server de web folosing modulul "manners"
		fmt.Fprintf(w, "Server shutting down ...")
		go func() {
			time.Sleep(1 * time.Second)
			fmt.Println("Server shutting down ...")
			manners.Close()
		}()
	})

	r.HandleFunc("/test/{oid}", func(w http.ResponseWriter, r *http.Request) {

		vars := mux.Vars(r)
		oid := vars["oid"]

		fmt.Printf("/test m=%s oid=%s q=%v\n", r.Method, oid, r.URL.Query())

		// post
		decoder := json.NewDecoder(r.Body)
		var args interface{} // generic - orice fel de obiect json
		err := decoder.Decode(&args)
		if err != nil {
			fmt.Printf("\tError: %v\n", err)
		} else {
			fmt.Printf("\ttest POST args  = %v\n", args)
			prettyJSON, err := json.MarshalIndent(args, "", "    ")
			if err == nil {
				fmt.Println(string(prettyJSON))
			}

		}

		// time.Sleep(1 * time.Second) // for test timeout
		var ret dict = dict{"ok": true, "method": r.Method, "da": false, "x": dict{"a": 1, "b": true, "c": dict{"ax": 33, "bx": 34}}}
		w.Header().Set("Content-Type", "application/json")
		jsonString, _ := json.Marshal(ret)
		fmt.Fprint(w, string(jsonString))
	})

	r.PathPrefix("/static/").Handler(http.FileServer(http.FS(static_fs)))

	addr := ":8080"
	fmt.Printf("Start webserver on %s\n", addr)
	err = manners.ListenAndServe(bindaddr, r)
	if err != nil {
		panic(err)
	}
	fmt.Println("End app.")
}

Exemplul de server de mai sus include, dupa compilare, continutul folderelor static si templates folosind modulul embed.

Pentru executia programului este nevoie numai de fisierul binar generat (aproximativ 9.6 mega), pentru ca in interiorul executabilului este inserat (embed) continutul folderelor static si templates.

Folderul templates contine cel putin 3 fisiere: index.tmpl, header.tmpl si footer.tmpl.

index.tmpl


{{define "index"}}
{{template "header" .}}

<h3>{{.title}}</h3>

<script>

    (async () => {
        var ret = null

        ret = await getFetch('/test/100?a=1&b=222')
        if (typeof (ret) != 'object') console.log("Err", ret)
        else console.log("call 1 =", ret)

        ret = await postFetch('/test/200?a=333&b=444', { a: 1 })
        if (typeof (ret) != 'object') console.log("Err", ret)
        else console.log("call 2 =", ret)

    })()

</script>

{{template "footer" .}}
{{end}}

header.tmpl


{{define "header"}}

<html lang="en">
<head>
   
   <meta content="IE=edge" http-equiv="X-UA-Compatible">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   
   <link rel="stylesheet" type="text/css" href="/static/app.css">
   <script src="/static/app.js"></script>


{{end}}

footer.tmpl


{{define "footer"}}
</body>
</html>
{{end}}

Folderul static contine fisiere .css si .js necesare aplicatiei livrate de serverul de web.


Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric


Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.