Martini Go dilinde hızlı ve modüler web uygulamaları ve servisleri için güçlü bir pakettir.
Go kurulumu ve GOPATH ayarını yaptıktan sonra, ilk .go
uzantılı dosyamızı oluşturuyoruz. Bu oluşturduğumuz dosyayı server.go
olarak adlandıracağız.
package main
import "github.com/go-martini/martini"
func main() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
}
Martini paketini kurduktan sonra (go 1.1 ve daha üst go sürümü gerekmektedir.):
go get github.com/go-martini/martini
Daha sonra server'ımızı çalıştırıyoruz:
go run server.go
Şimdi elimizde çalışan bir adet Martini webserver localhost:3000
adresinde bulunmaktadır.
Stackoverflow üzerinde martini etiketine sahip sorular
GO Diline ait Dökümantasyonlar
- Oldukça basit bir kullanıma sahip.
- Kısıtlama yok.
- Golang paketleri ile rahat bir şekilde kullanılıyor.
- Müthiş bir şekilde path eşleştirme ve yönlendirme.
- Modüler dizayn - Kolay eklenen fonksiyonellik.
- handlers/middlewares kullanımı çok iyi.
- Büyük 'kutu dışarı' özellik seti.
- http.HandlerFunc arayüzü ile tam uyumludur.
- Varsayılan belgelendirme işlemleri (örnek olarak, AngularJS uygulamalarının HTML5 modunda servis edilmesi).
Daha fazla ara katman ve fonksiyonellik için, şu repoları inceleyin martini-contrib.
martini.Classic() hızlıca projeyi çalıştırır ve çoğu web uygulaması için iyi çalışan bazı makul varsayılanlar sağlar:
m := martini.Classic()
// ... middleware and routing goes here
m.Run()
martini.Classic() aşağıdaki bazı fonsiyonelleri otomatik olarak çeker:
- İstek/Yanıt Kayıtları (Request/Response Logging) - martini.Logger
- Hataların Düzeltilmesi (Panic Recovery) - martini.Recovery
- Statik Dosyaların Sunumu (Static File serving) - martini.Static
- Yönlendirmeler (Routing) - martini.Router
İşleyiciler Martini'nin ruhu ve kalbidir. Bir işleyici temel olarak her türlü fonksiyonu çağırabilir:
m.Get("/", func() {
println("hello world")
})
Eğer bir işleyici geriye bir şey dönderiyorsa, Martini string olarak sonucu http.ResponseWriter ile yazacaktır:
m.Get("/", func() string {
return "hello world" // HTTP 200 : "hello world"
})
Ayrıca isteğe bağlı bir durum kodu dönderebilir:
m.Get("/", func() (int, string) {
return 418, "i'm a teapot" // HTTP 418 : "i'm a teapot"
})
İşlemciler yansıma yoluyla çağrılır. Martini Dependency Injection kullanarak arguman listesindeki bağımlıkları giderir.Bu sayede Martini go programlama dilinin http.HandlerFunc
arayüzü ile tamamen uyumlu hale getirilir.
Eğer işleyiciye bir arguman eklersek, Martini "type assertion" ile servis listesinde arayacak ve bağımlılıkları çözmek için girişimde bulunacaktır:
m.Get("/", func(res http.ResponseWriter, req *http.Request) { // res and req are injected by Martini
res.WriteHeader(200) // HTTP 200
})
Aşağıdaki servislerin içerikleri
- *log.Logger - Martini için Global loglayıcı.
- martini.Context - http request içereği.
- martini.Params -
map[string]string
ile yol eşleme tarafından params olarak isimlendirilen yapılar bulundu. - martini.Routes - Yönledirilme için yardımcı olan yapıdır.
- http.ResponseWriter - http yanıtlarını yazacak olan yapıdır.
- *http.Request - http Request(http isteği yapar).
Martini'de bir yol HTTP metodu URL-matching pattern'i ile eşleştirilir. Her bir yol bir veya daha fazla işleyici metod alabilir:
m.Get("/", func() {
// show something
})
m.Patch("/", func() {
// update something
})
m.Post("/", func() {
// create something
})
m.Put("/", func() {
// replace something
})
m.Delete("/", func() {
// destroy something
})
m.Options("/", func() {
// http options
})
m.NotFound(func() {
// handle 404
})
Yollar sırayla tanımlandıkları şekilde eşleştirilir.Request ile eşleşen ilk rota çağrılır.
Yol patternleri martini.Params servisi tarafından adlandırılan parametreleri içerebilir:
m.Get("/hello/:name", func(params martini.Params) string {
return "Hello " + params["name"]
})
Yollar globaller ile eşleşebilir:
m.Get("/hello/**", func(params martini.Params) string {
return "Hello " + params["_1"]
})
Düzenli ifadeler kullanılabilir:
m.Get("/hello/(?P<name>[a-zA-Z]+)", func(params martini.Params) string {
return fmt.Sprintf ("Hello %s", params["name"])
})
Düzenli ifadeler hakkında daha fazla bilgiyi Go dökümanlarından elde edebilirsiniz.
Yol işleyicileri birbirlerinin üstüne istiflenebilir. Bu durum doğrulama ve yetkilendirme(authentication and authorization) işlemleri için iyi bir yöntemdir:
m.Get("/secret", authorize, func() {
// this will execute as long as authorize doesn't write a response
})
Yol grupları Grup metodlar kullanılarak eklenebilir.
m.Group("/books", func(r martini.Router) {
r.Get("/:id", GetBooks)
r.Post("/new", NewBook)
r.Put("/update/:id", UpdateBook)
r.Delete("/delete/:id", DeleteBook)
})
Tıpkı ara katmanların işleyiciler için bazı ara katman işlemlerini atlayabileceği gibi gruplar içinde atlayabilir.
m.Group("/books", func(r martini.Router) {
r.Get("/:id", GetBooks)
r.Post("/new", NewBook)
r.Put("/update/:id", UpdateBook)
r.Delete("/delete/:id", DeleteBook)
}, MyMiddleware1, MyMiddleware2)
Servisler işleyicilerin arguman listesine enjekte edilecek kullanılabilir nesnelerdir. İstenildiği taktirde bir servis Global ve Request seviyesinde eşlenebilir.
Bir martini örneği(instance) projeye enjekte edilir. A Martini instance implements the inject.Enjekte arayüzü, çok kolay bir şekilde servis eşlemesi yapar:
db := &MyDatabase{}
m := martini.Classic()
m.Map(db) // the service will be available to all handlers as *MyDatabase
// ...
m.Run()
Request düzeyinde eşleme yapmak üzere işleyici martini.Context ile oluşturulabilir:
func MyCustomLoggerHandler(c martini.Context, req *http.Request) {
logger := &MyCustomLogger{req}
c.Map(logger) // mapped as *MyCustomLogger
}
Servisler hakkındaki en güçlü şeylerden birisi bir arabirim ile bir servis eşleşmektedir. Örneğin, istenirse http.ResponseWriter yapısı paketlenmiş ve ekstra işlemleri gerçekleştirilen bir nesne ile override edilebilir. Şu işleyici yazılabilir:
func WrapResponseWriter(res http.ResponseWriter, c martini.Context) {
rw := NewSpecialResponseWriter(res)
c.MapTo(rw, (*http.ResponseWriter)(nil)) // override ResponseWriter with our wrapper ResponseWriter
}
martini.Classic() örneği otomatik olarak statik dosyaları serverda root içinde yer alan "public" dizininden servis edilir.
Eğer istenirse daha fazla martini.Static işleyicisi eklenerek daha fazla dizin servis edilebilir.
m.Use(martini.Static("assets")) // serve from the "assets" directory as well
Eğer istenilen URL bulunamaz ise özel bir URL dönderilebilir. Ayrıca bir dışlama(exclusion) ön eki ile bazı URL'ler göz ardı edilir. Bu durum statik dosyaların ve ilave işleyiciler için kullanışlıdır(Örneğin, REST API). Bunu yaparken, bu işlem ile NotFound zincirinin bir parçası olan statik işleyiciyi tanımlamak kolaydır.
Herhangi bir URL isteği bir local dosya ile eşleşmediği ve /api/v
ile başlamadığı zaman aşağıdaki örnek /index.html
dosyasını sonuç olarak geriye döndürecektir.
static := martini.Static("assets", martini.StaticOptions{Fallback: "/index.html", Exclude: "/api/v"})
m.NotFound(static, http.NotFound)
Ara katmana ait işleyiciler http isteği ve yönlendirici arasında bulunmaktadır. Özünde onlar diğer Martini işleyicilerinden farklı değildirler. İstenildiği taktirde bir yığına ara katman işleyicisi şu şekilde eklenebilir:
m.Use(func() {
// do some middleware stuff
})
Handlers
fonksiyonu ile ara katman yığını üzerinde tüm kontrole sahip olunabilir. Bu daha önceden ayarlanmış herhangi bir işleyicinin yerini alacaktır:
m.Handlers(
Middleware1,
Middleware2,
Middleware3,
)
Orta katman işleyicileri loglama, giriş , yetkilendirme , sessionlar, sıkıştırma(gzipping) , hata sayfaları ve HTTP isteklerinden önce ve sonra herhangi bir olay sonucu oluşan durumlar için gerçekten iyi bir yapıya sahiptir:
// validate an api key
m.Use(func(res http.ResponseWriter, req *http.Request) {
if req.Header.Get("X-API-KEY") != "secret123" {
res.WriteHeader(http.StatusUnauthorized)
}
})
Context.Next() orta katman işleyicilerinin diğer işleyiciler yok edilmeden çağrılmasını sağlayan opsiyonel bir fonksiyondur.Bu iş http işlemlerinden sonra gerçekleşecek işlemler için gerçekten iyidir:
// log before and after a request
m.Use(func(c martini.Context, log *log.Logger){
log.Println("before a request")
c.Next()
log.Println("after a request")
})
Bazı Martini işleyicileri martini.Env
yapısının özel fonksiyonlarını kullanmak için geliştirici ortamları, üretici ortamları vs. kullanır.Bu üretim ortamına Martini sunucu kurulurken MARTINI_ENV=production
şeklinde ortam değişkeninin ayarlanması gerekir.
martini-contrib projelerine bakarak başlayın. Eğer aradığınız şey orada mevcut değil ise yeni bir repo eklemek için martini-contrib takım üyeleri ile iletişime geçin.
- auth - Kimlik doğrulama için işleyiciler.
- binding - Mapping/Validating yapısı içinde ham request'i doğrulamak için kullanılan işleyici(handler)
- gzip - İstekleri gzip sıkışıtırıp eklemek için kullanılan işleyici
- render - Kolay bir şekilde JSON ve HTML şablonları oluşturmak için kullanılan işleyici.
- acceptlang -
Kabul edilen dile
göre HTTP başlığını oluşturmak için kullanılan işleyici. - sessions - Oturum hizmeti vermek için kullanılır.
- strip - İşleyicilere gitmeden önce URL'ye ait ön şeriti değiştirme işlemini yapar.
- method - Formlar ve başlık için http metodunu override eder.
- secure - Birkaç hızlı güvenlik uygulaması ile kazanımda bulundurur.
- encoder - Encoder servis veri işlemleri için çeşitli format ve içerik sağlar.
- cors - İşleyicilerin CORS desteği bulunur.
- oauth2 - İşleyiciler OAuth 2.0 için Martini uygulamalarına giriş sağlar. Google , Facebook ve Github için desteği mevcuttur.
- vauth - Webhook için giriş izni sağlar. (şimdilik sadece GitHub ve TravisCI ile)
Bir martini örneği http.Handler
'ı projeye dahil eder, bu sayde kolay bir şekilde mevcut olan Go sunucularında bulunan alt ağaçlarda kullanabilir. Örnek olarak, bu olay Google App Engine için hazırlanmış Martini uygulamalarında kullanılmaktadır:
package hello
import (
"net/http"
"github.com/go-martini/martini"
)
func init() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
http.Handle("/", m)
}
Martini'ye ait Run
fonksiyounu PORT ve HOST'a ait ortam değişkenlerini arar ve bunları kullanır. Aksi taktirde standart olarak localhost:3000 adresini port ve host olarak kullanacaktır.
Port ve host için daha fazla esneklik isteniyorsa martini.RunOnAddr
fonksiyonunu kullanın.
m := martini.Classic()
// ...
log.Fatal(m.RunOnAddr(":8080"))
gin ve fresh anlık kod yüklemeleri yapan martini uygulamalarıdır.
Martini'nin temiz ve düzenli olaması gerekiyordu. Martini is meant to be kept tiny and clean. Tüm kullanıcılar katkı yapmak için martini-contrib organizasyonunda yer alan repoları bitirmelidirler. Eğer martini core için katkıda bulunacaksanız fork işlemini yaparak başlayabilirsiniz.
express ve sinatra projelerinden esinlenmiştir.
Martini Code Gangsta tarafından tasarlanılmıştır.