import "github.com/guregu/kami"
หรือ import "gopkg.in/guregu/kami.v2"
Kami (神) เป็นเฟรมเวิร์กเว็บเล็ก ๆ โดยใช้บริบทสำหรับบริบทการร้องขอและ httptreemux สำหรับการกำหนดเส้นทาง มันมีระบบง่ายๆสำหรับการรันมิดเดิลแวร์แบบลำดับชั้นก่อนและหลังการร้องขอนอกเหนือจากการบันทึกและตะขอตื่นตระหนก การรีสตาร์ทที่สง่างามผ่าน Einhorn ก็รองรับ
Kami ได้รับการออกแบบให้ใช้เป็นจุดลงทะเบียนกลางสำหรับเส้นทางของคุณมิดเดิลแวร์และบริบทของ "God Object" คุณได้รับการสนับสนุนให้ใช้ฟังก์ชั่นทั่วโลก แต่ Kami รองรับ Muxes หลายตัวด้วย kami.New()
คุณมีอิสระที่จะเมานต์ kami.Handler()
ไม่ว่าคุณจะต้องการ แต่มีฟังก์ชั่น kami.Serve()
ที่เป็นประโยชน์
นี่คืองานนำเสนอเกี่ยวกับการเกิดของคามิอธิบายตัวเลือกการออกแบบบางอย่าง
รองรับทั้ง context
และ x/net/context
ตัวอย่างที่วางแผนไว้โดยใช้คามิและบริบทเพื่อแปลคำทักทาย
ข้าม⏩
// WebServerPackage MainImport ของเรา ("fmt" "Net/http" "บริบท" "github.com/guregu/kami" "github.com/my-github/greeting" // ดูแพคเกจคำทักทายด้านล่าง) Func Greet (บริบท CTX บริบท, w http.responsewriter, r *http.request) {สวัสดี: = Greeting.FromContext (CTX) ชื่อ: = kami.param (ctx, "name") fmt.fprintf (w, " %s, %s!", สวัสดี, ชื่อ) } func main () {ctx: = context.background () ctx = greeting.withcontext (ctx, "hello") // ตั้งค่าเริ่มต้น greetingkami.context = ctx // ตั้งค่าบริบทของพระเจ้า " . ใช้ ("/สวัสดี/", ทักทาย. guess) // ใช้มิดเดิลแวร์นี้สำหรับเส้นทางภายใต้ /hello/kami.get("/hello/:name ", ทักทาย) // เพิ่มตัวจัดการ Get ด้วยพารามิเตอร์ใน urlkami.serve () // เสิร์ฟอย่างสง่างามด้วยการสนับสนุนสำหรับ einhorn และ systemd}
// แพ็คเกจทักทายร้านค้าการตั้งค่าการทักทายในบริบทแพคเกจทักทาย Import ("net/http" "บริบท" "golang.org/x/text/language") // สำหรับข้อมูลเพิ่มเติมเกี่ยวกับบริบทและทำไมเรากำลังทำสิ่งนี้ // ดู https://blog.golang.org/contexttype ctxkey intvar key ctxkey = 0var greetings = map [language.tag] สตริง { language.americanenglish: "yo", language.japanese: "こんにちは", } // Guess คือ Kami Middleware ที่ตรวจสอบการยอมรับภาษาและชุด // คำทักทายให้ดีกว่าถ้าเป็นไปได้ , _, err: = language.parseAcceptLanguage (r.header.get ("ยอมรับภาษา")); err == nil {สำหรับ _, t: = ช่วงแท็ก {ถ้า g, ตกลง: = ทักทาย [t]; ตกลง {ctx = withcontext (ctx, g) return ctx - - } ส่งคืน ctx} // withcontext ส่งคืนบริบทใหม่ด้วยคำอวยพรที่กำหนด func withcontext (ctx context.contex } // fromContext ดึงคำทักทายจากบริบทนี้ // หรือส่งคืนสตริงว่างถ้าหายไป fruntcontext (ctx context.context) สตริง {hello, _: = ctx.value (คีย์)
ตั้งค่าเส้นทางโดยใช้ kami.Get("/path", handler)
, kami.Post(...)
ฯลฯ คุณสามารถใช้พารามิเตอร์ชื่อหรือไวด์การ์ดใน URL เช่น /hello/:name/edit
or /files/*path
และเข้าถึงพวกเขาโดยใช้บริบท kami ให้คุณ: kami.Param(ctx, "name")
ดูกฎการกำหนดเส้นทางและลำดับความสำคัญการกำหนดเส้นทาง ยอมรับตัวจัดการประเภทต่อไปนี้:
ประเภทที่ใช้ kami.ContextHandler
func(context.Context, http.ResponseWriter, *http.Request)
ประเภทที่ใช้ http.Handler
func(http.ResponseWriter, *http.Request)
บริบททั้งหมดที่คามิใช้สืบเชื้อสายมาจาก kami.Context
: นี่คือ "วัตถุพระเจ้า" และชื่อของโครงการนี้ โดยค่าเริ่มต้นนี่คือ context.Background()
แต่อย่าลังเลที่จะแทนที่ด้วยบริบทก่อนเริ่มต้นที่เหมาะสมสำหรับแอปพลิเคชันของคุณ
การสร้างเป้าหมายการกำหนดเป้าหมายของ Google App Engine จะสรุปบริบท "วัตถุพระเจ้า" โดยอัตโนมัติด้วยบริบทต่อคำตอบของเอ็นจินเอ็นจิ้น
เพิ่มมิดเดิลแวร์ด้วย kami.Use("/path", kami.Middleware)
มิดเดิลแวร์ทำงานก่อนการร้องขอและสามารถหยุดพวกเขาได้เร็ว เพิ่มเติมเกี่ยวกับมิดเดิลแวร์ด้านล่าง
เพิ่ม Afterware ด้วย kami.After("/path", kami.Afterware)
Afterware ทำงานหลังจากคำขอ
ตั้งค่า kami.Cancel
เป็น true
เพื่อยกเลิกบริบทของคำขอทั้งหมดโดยอัตโนมัติหลังจากคำขอเสร็จสิ้น ซึ่งแตกต่างจากไลบรารีมาตรฐานคามิไม่ได้ยกเลิกบริบทตามค่าเริ่มต้น
คุณสามารถให้ตัวจัดการตื่นตระหนกได้โดยการตั้งค่า kami.PanicHandler
เมื่อมีการเรียกตัวจัดการตื่นตระหนกคุณสามารถเข้าถึงข้อผิดพลาดตื่นตระหนกด้วย kami.Exception(ctx)
นอกจากนี้คุณยังสามารถให้ kami.LogHandler
ที่จะห่อทุกคำขอ kami.LogHandler
มีลายเซ็นฟังก์ชั่นที่แตกต่างกันโดยใช้ writerproxy ที่สามารถเข้าถึงรหัสสถานะการตอบกลับ ฯลฯ
ใช้ kami.Serve()
เพื่อให้บริการแอปพลิเคชันของคุณอย่างสง่างามหรือ Mount kami.Handler()
ที่ใดที่สะดวก
พิมพ์ middleware func (context.context, http.responsewriter, *http.request) context.context
มิดเดิลแวร์แตกต่างจาก HandlerType ซึ่งจะส่งคืนบริบทใหม่ คุณสามารถใช้ประโยชน์จากสิ่งนี้เพื่อสร้างบริบทของคุณโดยการลงทะเบียนมิดเดิลแวร์ที่เส้นทาง Approriate เป็นกรณีพิเศษคุณสามารถคืน NIL เพื่อหยุดการดำเนินการของห่วงโซ่มิดเดิลแวร์
มิดเดิลแวร์เป็นลำดับชั้น ตัวอย่างเช่นคำขอ /hello/greg
จะเรียกใช้มิดเดิลแวร์ที่ลงทะเบียนภายใต้เส้นทางต่อไปนี้ตามลำดับ:
/
/hello/
/hello/greg
ภายในเส้นทางมิดเดิลแวร์จะทำงานตามลำดับการลงทะเบียน
func init () {kami.use ("/", เข้าสู่ระบบ) kami.use ("/ส่วนตัว/", loginrequired) } // การเข้าสู่ระบบส่งคืนบริบทใหม่ด้วยวัตถุผู้ใช้ appropiate InsideFunc เข้าสู่ระบบ (ctx context.context, w http.responsewriter, r *http.request) บริบท. contentext {ถ้า u, err: = user.getByToken (ctx, r formValue ("auth_token")); err == nil {ctx = user.newcontext (ctx, u) } return ctx} // loginrequired หยุดคำขอหากเราไม่มี ObjectFunc ผู้ใช้ LoginRequired (ctx context.context, w http.ResponSewriter, r *http.request) context.context {ถ้า _, ok: = user.fromcontext (CTX); ! ok {W.WriteHeader (http.statusforbidden) // ... เรนเดอร์ 503 ต้องห้าม pagereturn nil } return ctx}
รองรับพารามิเตอร์และไวด์การ์ดในมิดเดิลแวร์ได้รับการสนับสนุนในขณะนี้ มิดเดิลแวร์ที่ลงทะเบียนภายใต้เส้นทางที่มีตัวแทนจะทำงาน หลังจาก มิดเดิลแวร์แบบลำดับชั้นทั้งหมด
kami.use ("/ผู้ใช้/: id/แก้ไข", checkadminpermissions) // ตรงกับเท่านั้น /user/:id/editkami.use("/user/:id/edit/* " ทำงานเหมือนเส้นทางที่ไม่ได้พารามิเตอร์
คามิสามารถใช้มิดเดิลแวร์วานิลลา HTTP ได้เช่นกัน kami.Use
ยอมรับฟังก์ชั่นในรูปแบบของ func(next http.Handler) http.Handler
ขอแนะนำว่าคามิจะเรียกใช้มิดเดิลแวร์ดังกล่าวตามลำดับไม่ใช่ในห่วงโซ่ ซึ่งหมายความว่าคนตัดไม้มาตรฐานและตัวจัดการตื่นตระหนกจะไม่ทำงานอย่างที่คุณคาดหวัง คุณควรใช้ kami.LogHandler
และ kami.PanicHandler
แทน
ตัวอย่างต่อไปนี้ใช้ goji/httpauth เพื่อเพิ่มการรับรองความถูกต้องพื้นฐาน HTTP ไปยังเส้นทางภายใต้ /secret/
นำเข้า ("github.com/goji/httpauth""งูบ.com/guregu/kami") main () {kami.use ("/ความลับ/", httpauth.simplebasicauth (" ชื่อผู้ใช้ "," รหัสผ่าน ")) .get ("/Secret/Message", SecretMessageHandler) kami.serve () -
พิมพ์ funcware func (context.context, mutil.writerproxy, *http.request) context.context
func init () {kami.after ("/", cleanup) -
รันหลังจากตัวจัดการคำขอหลังจากนั้นมีประโยชน์สำหรับการทำความสะอาด Afterware เป็นเหมือนภาพสะท้อนของมิดเดิลแวร์ Afterware ยังทำงานตามลำดับชั้น แต่ในลำดับย้อนกลับของมิดเดิลแวร์ ไวด์การ์ดจะได้รับการประเมิน ก่อนที่ จะมีลำดับชั้นหลังแวร์
ตัวอย่างเช่นคำขอ /hello/greg
จะทำงานหลังจากที่ลงทะเบียนภายใต้เส้นทางต่อไปนี้:
/hello/greg
/hello/
/
สิ่งนี้ให้ Afterware ภายใต้เส้นทางที่เฉพาะเจาะจงความสามารถในการใช้ทรัพยากรที่อาจปิดโดย /
ซึ่งแตกต่างจากมิดเดิลแวร์ Afterware ที่กลับมา ไม่มีศูนย์ จะไม่หยุดหลังจากที่ได้รับการประเมิน
kami.After("/path", afterware)
รองรับฟังก์ชั่นหลายประเภทดูเอกสารสำหรับ kami.AfterwareType
สำหรับรายละเอียดเพิ่มเติม
*kami.Mux
Kami ได้รับการออกแบบมาเพื่อเป็น "กาว" ระหว่างหลายแพ็คเกจในเว็บแอปพลิเคชันที่ซับซ้อน ฟังก์ชั่นทั่วโลกและ kami.Context
เป็นวิธีที่ง่ายสำหรับแพ็คเกจของคุณในการทำงานร่วมกัน อย่างไรก็ตามหากคุณต้องการใช้ Kami เป็นเซิร์ฟเวอร์ฝังตัวภายในแอพอื่นให้บริการสแต็คคามิสองตัวแยกกันบนพอร์ตที่แตกต่างกันหรือไม่ก็อยากจะมี Kami รุ่นที่ไม่ใช่ Global, kami.New()
อาจมีประโยชน์
การโทรหา kami.New()
ส่งคืน *kami.Mux
สดใหม่ซึ่งเป็นสแต็คคามิอิสระอย่างสมบูรณ์ การเปลี่ยนแปลง kami.Context
เส้นทางที่ลงทะเบียนกับ kami.Get()
et al และมิดเดิลแวร์ทั่วโลกที่ลงทะเบียนกับ kami.Use()
จะไม่ส่งผลกระทบต่อ *kami.Mux
แทนด้วย mux := kami.New()
คุณสามารถเปลี่ยน mux.Context
โทร mux.Use()
, mux.Get()
, mux.NotFound()
ฯลฯ
*kami.Mux
ใช้ http.Handler
ดังนั้นคุณอาจใช้มันตามที่คุณต้องการ!
// Package Admin เป็นผู้ดูแลระบบเว็บเซิร์ฟเวอร์ PluginPackage Adminimport ("NET/http" "github.com/guregu/kami") // ติดตั้ง Secret Admin Admin Initfunc () {mux: = kami.new () mux context = adminConTextMux.use ("/", อนุญาต) mux.get ("/admin/memstats", หน่วยความจำ) mux.post ("/admin/die", shutdown) // ... http.handle ("/admin/", mux) -
มิกซ์
httptreemux: เราเตอร์
Goji: สง่างามนักเขียน