Martini - мощный пакет для быстрой разработки веб приложений и сервисов на Golang.
После установки Golang и настройки вашего GOPATH, создайте ваш первый .go
файл. Назовем его server.go
.
package main
import "github.com/go-martini/martini"
func main() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
}
Потом установите пакет Martini (требуется go 1.1 или выше):
go get github.com/go-martini/martini
Потом запустите ваш сервер:
go run server.go
И вы получите запущенный Martini сервер на localhost:3000
.
Присоединяйтесь к рассылке
Задавайте вопросы на Stackoverflow используя тэг martini
GoDoc документация
- Очень прост в использовании.
- Ненавязчивый дизайн.
- Хорошо сочетается с другими пакетами.
- Потрясающий роутинг и маршрутизация.
- Модульный дизайн - легко добавлять и исключать функциональность.
- Большое количество хороших обработчиков/middlewares, готовых к использованию.
- Отличный набор 'из коробки'.
- Полностью совместим с интерфейсом http.HandlerFunc.
Смотрите репозитории организации martini-contrib, для большей информации о функциональности и middleware.
Для быстрого старта martini.Classic() предлагает несколько предустановок, это используется для большинства веб приложений:
m := martini.Classic()
// ... middleware и роутинг здесь
m.Run()
Ниже представлена уже подключенная martini.Classic() функциональность:
- Request/Response логгирование - martini.Logger
- Panic Recovery - martini.Recovery
- Отдача статики - martini.Static
- Роутинг - martini.Router
Обработчики - это сердце и душа Martini. Обработчик - любая функция, которая может быть вызвана:
m.Get("/", func() {
println("hello world")
})
Если обработчик возвращает что-либо, Martini запишет это как результат в текущий http.ResponseWriter, в виде строки:
m.Get("/", func() string {
return "hello world" // HTTP 200 : "hello world"
})
Так же вы можете возвращать код статуса, опционально:
m.Get("/", func() (int, string) {
return 418, "i'm a teapot" // HTTP 418 : "i'm a teapot"
})
Обработчики вызываются посредством рефлексии. Martini использует Внедрение зависимости для разрешения зависимостей в списке аргумента обработчика. Это делает Martini полностью совместимым с интерфейсом http.HandlerFunc
.
Если вы добавите аргументы в ваш обработчик, Martini будет пытаться найти этот список сервисов за счет проверки типов(type assertion):
m.Get("/", func(res http.ResponseWriter, req *http.Request) { // res и req будут внедрены Martini
res.WriteHeader(200) // HTTP 200
})
Следующие сервисы включены в martini.Classic():
- *log.Logger - Глобальный логгер для Martini.
- martini.Context - http request контекст.
- martini.Params -
map[string]string
именованных аргументов из роутера. - martini.Routes - Хэлпер роутеров.
- http.ResponseWriter - http Response writer интерфейс.
- *http.Request - http Request.
В Martini, роут - это объединенные паттерн и HTTP метод. Каждый роут может принимать один или несколько обработчиков:
m.Get("/", func() {
// показать что-то
})
m.Patch("/", func() {
// обновить что-то
})
m.Post("/", func() {
// создать что-то
})
m.Put("/", func() {
// изменить что-то
})
m.Delete("/", func() {
// удалить что-то
})
m.Options("/", func() {
// http опции
})
m.NotFound(func() {
// обработчик 404
})
Роуты могут сопоставляться с http запросами только в порядке объявления. Вызывается первый роут, который соответствует запросу.
Паттерны роутов могут включать именованные параметры, доступные через martini.Params сервис:
m.Get("/hello/:name", func(params martini.Params) string {
return "Hello " + params["name"]
})
Роуты можно объявлять как glob'ы:
m.Get("/hello/**", func(params martini.Params) string {
return "Hello " + params["_1"]
})
Так же могут использоваться регулярные выражения:
m.Get("/hello/(?P<name>[a-zA-Z]+)", func(params martini.Params) string {
return fmt.Sprintf ("Hello %s", params["name"])
})
Синтаксис регулярных выражений смотрите Go documentation.
Обработчики роутов так же могут быть выстроены в стек, друг перед другом. Это очень удобно для таких задач как авторизация и аутентификация:
m.Get("/secret", authorize, func() {
// будет вызываться, в случае если authorize ничего не записал в ответ
})
Роуты так же могут быть объединены в группы, посредством метода Group:
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)
})
Так же как вы можете добавить middleware для обычного обработчика, вы можете добавить middleware и для группы.
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)
Сервисы - это объекты, которые доступны для внедрения в аргументы обработчиков. Вы можете замапить сервисы на уровне всего приложения либо на уровне запроса.
Экземпляр Martini реализует интерфейс inject.Injector, поэтому замаппить сервис легко:
db := &MyDatabase{}
m := martini.Classic()
m.Map(db) // сервис будет доступен для всех обработчиков как *MyDatabase
// ...
m.Run()
Маппинг на уровне запроса можно сделать при помощи martini.Context:
func MyCustomLoggerHandler(c martini.Context, req *http.Request) {
logger := &MyCustomLogger{req}
c.Map(logger) // как *MyCustomLogger
}
Одна из мощных частей, того что касается сервисов - маппинг сервиса на определенный интерфейс. Например, если вы хотите переопределить http.ResponseWriter объектом, который оборачивает и добавляет новые операции, вы можете написать следующее:
func WrapResponseWriter(res http.ResponseWriter, c martini.Context) {
rw := NewSpecialResponseWriter(res)
c.MapTo(rw, (*http.ResponseWriter)(nil)) // переопределить ResponseWriter нашей оберткой
}
Экземпляр martini.Classic() автоматически отдает статические файлы из директории "public" в корне, рядом с вашим файлом server.go
.
Вы можете добавить еще директорий, добавляя martini.Static обработчики.
m.Use(martini.Static("assets")) // отдача файлов из "assets" директории
Middleware обработчики находятся между входящим http запросом и роутом. По сути, они ничем не отличаются от любого другого обработчика Martini. Вы можете добавить middleware обработчик в стек следующим образом:
m.Use(func() {
// делать какую то middleware работу
})
Для полного контроля над стеком middleware существует метод Handlers
. В этом примере будут заменены все обработчики, которые были до этого:
m.Handlers(
Middleware1,
Middleware2,
Middleware3,
)
Middleware обработчики очень хорошо работают для таких вещей как логгирование, авторизация, аутентификация, сессии, сжатие, страницы ошибок и любые другие операции, которые должны быть выполнены до или после http запроса:
// валидация api ключа
m.Use(func(res http.ResponseWriter, req *http.Request) {
if req.Header.Get("X-API-KEY") != "secret123" {
res.WriteHeader(http.StatusUnauthorized)
}
})
Context.Next() опциональная функция, которая может быть вызвана в Middleware обработчике, для выхода из контекста, и возврата в него, после вызова всего стека обработчиков. Это можно использовать для операций, которые должны быть выполнены после http запроса:
// логгирование до и после http запроса
m.Use(func(c martini.Context, log *log.Logger){
log.Println("до запроса")
c.Next()
log.Println("после запроса")
})
Некоторые Martini обработчики используют глобальную переменную martini.Env
для того, чтоб предоставить специальную функциональность для девелопмент и продакшн окружения. Рекомендуется устанавливать MARTINI_ENV=production
, когда вы деплоите приложение на продакшн.
Начните поиск с martini-contrib проектов. Если нет ничего подходящего, без колебаний пишите члену команды martini-contrib о добавлении нового репозитория в организацию.
- auth - Обработчики для аутентификации.
- binding - Обработчик для маппинга/валидации сырого запроса в определенную структуру(struct).
- gzip - Обработчик, добавляющий gzip сжатие для запросов.
- render - Обработчик, которые предоставляет сервис для легкого рендеринга JSON и HTML шаблонов.
- acceptlang - Обработчик для парсинга
Accept-Language
HTTP заголовка. - sessions - Сервис сессий.
- strip - Удаление префиксов из URL.
- method - Подмена HTTP метода через заголовок.
- secure - Набор для безопасности.
- encoder - Сервис для представления данных в нескольких форматах и взаимодействия с контентом.
- cors - Поддержка CORS.
- oauth2 - Обработчик, предоставляющий OAuth 2.0 логин для Martini приложений. Вход через Google, Facebook и через Github поддерживаются.
Экземпляр Martini реализует интерфейс http.Handler
, потому - это очень просто использовать вместе с существующим Go проектом. Например, это работает для платформы Google App Engine:
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)
}
Функция Run
смотрит переменные окружиения PORT и HOST, и использует их.
В противном случае Martini по умолчанию будет использовать localhost:3000
.
Для большей гибкости используйте вместо этого функцию martini.RunOnAddr
.
m := martini.Classic()
// ...
log.Fatal(m.RunOnAddr(":8080"))
gin и fresh могут работать вместе с Martini.
Подразумевается что Martini чистый и маленький. Большинство улучшений должны быть в организации martini-contrib. Но если вы хотите улучшить ядро Martini, отправляйте пулл реквесты.
Martini создан Code Gangsta