import "github.com/guregu/kami"
atau import "gopkg.in/guregu/kami.v2"
Kami (神) adalah kerangka kerja web kecil menggunakan konteks untuk konteks permintaan dan httptreemux untuk perutean. Ini termasuk sistem sederhana untuk menjalankan middleware hierarkis sebelum dan sesudah permintaan, selain log dan panik kait. Restart anggun melalui Einhorn juga didukung.
Kami dirancang untuk digunakan sebagai titik pendaftaran pusat untuk rute, middleware, dan konteks "objek dewa" Anda. Anda didorong untuk menggunakan fungsi global, tetapi Kami mendukung banyak mux dengan kami.New()
.
Anda bebas untuk memasang kami.Handler()
Di mana pun Anda inginkan, tetapi fungsi kami.Serve()
yang membantu disediakan.
Berikut adalah presentasi tentang kelahiran Kami, menjelaskan beberapa pilihan desain.
Baik context
dan x/net/context
didukung.
Contoh yang dibuat -buat menggunakan Kami dan konteks untuk melokalisasi salam.
Lewati ⏩
// WebServerPackage kami MainiMport ("fmt" "net/http" "konteks" "github.com/guregu/kami" "github.com/my-github/greeting" // lihat paket salam di bawah) funce salam (konteks CTX. Konteks, w http.responsewriter, r *http.request) {hello: = salam.fromContext (ctx) Nama: = Kami.param (ctx, "name") fmt.fprintf (w, " %s, %s!", halo, nama) } func main () {ctx: = context.background () ctx = sreiet.withcontext (ctx, "hello") // atur default queskami.context = ctx // atur "konteks dewa" kami, konteks dasar untuk semua permintaankami .Use ("/hello/", salam.guess) // Gunakan middleware ini untuk jalan di bawah /hello/kami.get("/hello/name ", salam) // Tambahkan pawang get dengan parameter di urlkami.serve () // dengan anggun melayani dengan dukungan untuk einhorn dan systemd}
// Paket Salam Toko Pengaturan Ucapan di Context.Package Salam Ucapan ("Net/http" "konteks" "golang.org/x/text/language") // Untuk informasi lebih lanjut tentang konteks dan mengapa kami melakukan ini, // Lihat https://blog.golang.org/contextType ctxkey intvar key ctxkey = 0var ucapan = peta [language.tag] string { language.americanenglish: "yo", language.japanese: "こんにちは", } // tebak adalah middleware Kami yang memeriksa bahasa penerimaan dan set // salam ke yang lebih baik jika mungkin.func tebak (ctx context.context, w http.responsewriter, r *http.request) context.context {if tag, tag if tag, r *http.request) , _, err: = language.parseCceptLanguage (r.header.get ("menerima-bahasa")); err == nil {for _, t: = range tag {if g, ok: = salam [t]; ok {ctx = withcontext (ctx, g) return ctx } } } return ctx} // withcontext mengembalikan konteks baru dengan ucapan selamat yang diberikan denganContext (ctx context.context, ucapan string) context.context {return context.withValue (ctx, kunci, ucapan) } // FromContext mengambil ucapan dari konteks ini, // atau mengembalikan string kosong jika hilang
Mengatur rute menggunakan Kami.get /files/*path
kami.Get("/path", handler)
, kami.Post(...)
, dll. Anda dapat menggunakan parameter /hello/:name/edit
disebut , dan akses mereka menggunakan konteks yang diberikan Kami: kami.Param(ctx, "name")
. Lihat aturan perutean dan prioritas perutean. Jenis penangan berikut diterima:
Jenis yang mengimplementasikan kami.ContextHandler
func(context.Context, http.ResponseWriter, *http.Request)
Jenis yang mengimplementasikan http.Handler
func(http.ResponseWriter, *http.Request)
Semua konteks yang digunakan Kami diturunkan dari kami.Context
: Ini adalah "objek Tuhan" dan senama dari proyek ini. Secara default, ini adalah context.Background()
, tetapi jangan ragu untuk menggantinya dengan konteks pra-inisialisasi yang cocok untuk aplikasi Anda.
Builds Menargetkan Google App Engine akan secara otomatis membungkus konteks "objek dewa" dengan konteks per-request App Engine.
Tambahkan middleware dengan kami.Use("/path", kami.Middleware)
. Middleware berjalan sebelum permintaan dan dapat menghentikannya lebih awal. Lebih lanjut tentang middleware di bawah ini.
Tambahkan Afterware dengan kami.After("/path", kami.Afterware)
. Afterware berjalan setelah permintaan.
Setel kami.Cancel
ke true
untuk secara otomatis membatalkan konteks semua permintaan setelah permintaan selesai. Berbeda dengan pustaka standar, Kami tidak membatalkan konteks secara default.
Anda dapat memberikan penangan panik dengan mengatur kami.PanicHandler
. Ketika pawang panik dipanggil, Anda dapat mengakses kesalahan panik dengan kami.Exception(ctx)
.
Anda juga dapat memberikan kami.LogHandler
Loghandler yang akan membungkus setiap permintaan. kami.LogHandler
memiliki tanda tangan fungsi yang berbeda, mengambil WriterProxy yang memiliki akses ke kode status respons, dll.
Gunakan kami.Serve()
untuk melayani aplikasi Anda dengan anggun, atau mount kami.Handler()
di suatu tempat yang nyaman.
ketik func middleware (context.context, http.responsewriter, *http.request) context.context
Middleware berbeda dari handlerType karena mengembalikan konteks baru. Anda dapat memanfaatkan ini untuk membangun konteks Anda dengan mendaftarkan middleware di jalur yang tepat. Sebagai kasus khusus, Anda dapat mengembalikan NIL untuk menghentikan eksekusi rantai middleware.
Middleware adalah hierarkis. Misalnya, permintaan /hello/greg
akan menjalankan middleware terdaftar di bawah jalur berikut, dalam urutan:
/
/hello/
/hello/greg
Dalam jalur, middleware dijalankan dalam urutan pendaftaran.
func init () {Kami.use ("/", login) Kami.use ("/private/", loginrequired) } // Login Mengembalikan konteks baru dengan login Insidefunct Obyek Pengguna Prepopiate (CTX Context.Context, W http.Responsewriter, r *http.request) context.context {if u, err: = user.getByToken (ctx, r. FormValue ("auth_token")); err == nil {ctx = user.newcontext (ctx, u) } return ctx} // LoginRequired Menghentikan permintaan jika kita tidak memiliki pengguna ObjectFunc LoginRequired (CTX Context.Context, W http.Responsewriter, r *http.request) Context.context {if _, ok: = user.fromcontextext (CTX); ! Ok {w.writeHeader (http.statusforbidden) // ... render 503 Pagereturn terlarang nil } return ctx}
Parameter dan wildcard bernama di middleware didukung sekarang. Middleware terdaftar di bawah jalur dengan wildcard akan berjalan setelah semua middleware hierarkis.
Kami.use ("/user/: id/edit", checkadminpermissions) // cocok hanya /user/:id/editkami.use("/user/:id/edit/* ", periksa periksa) // cocok dengan semua jalur warisan warisan , berperilaku seperti jalur non-parameterisasi
Kami juga dapat menggunakan vanilla http middleware. kami.Use
menerima fungsi dalam bentuk func(next http.Handler) http.Handler
. Dianjurkan agar Kami akan menjalankan middleware tersebut secara berurutan, bukan dalam rantai. Ini berarti bahwa penangani standar dan penangan panik tidak akan berfungsi seperti yang Anda harapkan. Anda harus menggunakan kami.LogHandler
dan kami.PanicHandler
sebagai gantinya.
Contoh berikut menggunakan Goji/httpAuth untuk menambahkan otentikasi dasar http ke jalur di bawah /secret/
.
import ("github.com/goji/httpauth""github.com/guru/kami")func main () {Kami.use ("/Secret/", httpauth.simpleBasiuty (" nama pengguna "," kata sandi "))) Kamih. .Get ("/Secret/Message", SecretMessageHandler) Kami.serve () }
ketik func afterware (context.context, mutil.writerproxy, *http.request) context.context
func init () {Kami.after ("/", cleanup) }
Menjalankan setelah penangan permintaan, Afterware berguna untuk membersihkan. Afterware seperti gambar cermin middleware. Afterware juga berjalan secara hierarkis, tetapi dalam urutan terbalik middleware. Wildcard dievaluasi sebelum afterware hierarkis.
Misalnya, permintaan /hello/greg
akan menjalankan afterware yang terdaftar di bawah jalur berikut:
/hello/greg
/hello/
/
Ini memberi Afterware di bawah jalur tertentu kemampuan untuk menggunakan sumber daya yang mungkin ditutup oleh /
.
Tidak seperti Middleware, Afterware Returning NIL tidak akan menghentikan afterware yang tersisa untuk dievaluasi.
kami.After("/path", afterware)
mendukung berbagai jenis fungsi, lihat dokumen untuk kami.AfterwareType
untuk lebih jelasnya.
*kami.Mux
Kami awalnya dirancang untuk menjadi "lem" antara beberapa paket dalam aplikasi web yang kompleks. Fungsi global dan kami.Context
adalah cara mudah bagi paket Anda untuk bekerja bersama. Namun, jika Anda ingin menggunakan Kami sebagai server tertanam di dalam aplikasi lain, sajikan dua tumpukan kami yang terpisah di port yang berbeda, atau ingin memiliki versi non-global dari Kami, kami.New()
mungkin berguna.
Memanggil kami.New()
mengembalikan *kami.Mux
yang segar, tumpukan Kami yang sepenuhnya independen. Perubahan pada kami.Context
, jalur yang terdaftar dengan kami.Get()
et al, dan middleware global yang terdaftar dengan kami.Use()
tidak akan mempengaruhi *kami.Mux
.
Sebaliknya, dengan mux := kami.New()
Anda dapat mengubah mux.Context
, hubungi mux.Use()
, mux.Get()
, mux.NotFound()
, dll.
*kami.Mux
mengimplementasikan http.Handler
, jadi Anda dapat menggunakannya sesuka Anda!
// Paket Admin adalah admin Panel Server Web PluginPackage AdminImport ("net/http" "github.com/guru/kami") // secara otomatis memasang stufffunc init rahasia kami () {mux: = Kami.new () mux. Context = AdmincontextMux.use ("/", otorize) mux.get ("/admin/memstats", memorystats) mux.post ("/admin/die", shutdown) // ... http.handle ("/admin/", mux) }
Mit
httptreemux: router
Goji: anggun, penulis