Skip to content

Latest commit

 

History

History
358 lines (285 loc) · 15 KB

README_ko_kr.md

File metadata and controls

358 lines (285 loc) · 15 KB

Martini wercker statusGoDoc

마티니(Martini)는 강력하고 손쉬운 웹애플리케이션 / 웹서비스개발을 위한 Golang 패키지입니다.

시작하기

Go 인스톨 및 GOPATH 환경변수 설정 이후에, .go 파일 하나를 만들어 보죠..흠... 일단 server.go라고 부르겠습니다.

package main

import "github.com/go-martini/martini"

func main() {
  m := martini.Classic()
  m.Get("/", func() string {
    return "Hello, 세계!"
  })
  m.Run()
}

마티니 패키지를 인스톨 합니다. (go 1.1 혹은 그 이상 버젼 필요):

go get github.com/go-martini/martini

이제 서버를 돌려 봅시다:

go run server.go

마티니 웹서버가 localhost:3000에서 돌아가고 있는 것을 확인하실 수 있을 겁니다.

도움이 필요하다면?

메일링 리스트에 가입해 주세요

데모 비디오도 있어요.

혹은 Stackoverflow에 마티니 태크를 이용해서 물어봐 주세요

GoDoc 문서(documentation)

문제는 전부다 영어로 되어 있다는 건데요 -_-;;; 나는 한글 아니면 보기 싫다! 하는 분들은 아래 링크를 참조하세요

주요기능

  • 사용하기 엄청 쉽습니다.
  • 비간섭(Non-intrusive) 디자인
  • 다른 Golang 패키지들과 잘 어울립니다.
  • 끝내주는 경로 매칭과 라우팅.
  • 모듈형 디자인 - 기능추가가 쉽고, 코드 꺼내오기도 쉬움.
  • 유용한 핸들러와 미들웨어가 많음.
  • 훌륭한 패키지화(out of the box) 기능들
  • http.HandlerFunc 인터페이스와 호환율 100%

미들웨어(Middleware)

미들웨어들과 추가기능들은 martini-contrib에서 확인해 주세요.

목차

Classic Martini

마티니를 쉽고 빠르게 이용하시려면, martini.Classic()를 이용해 보세요. 보통 웹애플리케이션에서 사용하는 설정들이 이미 포함되어 있습니다.

  m := martini.Classic()
  // ... 미들웨어와 라우팅 설정은 이곳에 오면 작성하면 됩니다.
  m.Run()

아래는 martini.Classic()에 자동으로 제공되는 기본 기능들 입니다.

핸들러(Handlers)

핸들러(Handlers)는 마티니의 핵심입니다. 핸들러는 기본적으로 실행 가능한 모든 형태의 함수들입니다.

m.Get("/", func() {
  println("hello 세계")
})

반환 값 (Return Values)

핸들러가 반환을 하는 함수라면, 마티니는 반환 값을 http.ResponseWriter에 스트링으로 입력 할 것입니다.

m.Get("/", func() string {
  return "hello 세계" // HTTP 200 : "hello 세계"
})

원하신다면, 선택적으로 상태코드도 함께 반환 할 수 있습니다.

m.Get("/", func() (int, string) {
  return 418, "난 주전자야!" // HTTP 418 : "난 주전자야!"
})

서비스 주입(Service Injection)

핸들러들은 리플렉션을 통해 호출됩니다. 마티니는 의존성 주입을 이용해서 핸들러의 인수들을 주입합니다. 이것이 마티니를 http.HandlerFunc 인터페이스와 100% 호환할 수 있게 해줍니다.

핸들러의 인수를 입력했다면, 마티니가 서비스 목록들을 살펴본 후 타입확인(type assertion)을 통해 의존성문제 해결을 시도 할 것입니다.

m.Get("/", func(res http.ResponseWriter, req *http.Request) { // res와 req는 마티니에 의해 주입되었다.
  res.WriteHeader(200) // HTTP 200
})

아래 서비스들은 martini.Classic():에 포함되어 있습니다.

라우팅(Routing)

마티니에서 루트는 HTTP 메소드와 URL매칭 패턴의 페어입니다. 각 루트는 하나 혹은 그 이상의 핸들러 메소드를 가질 수 있습니다.

m.Get("/", func() {
  // 보여줘 봐
})

m.Patch("/", func() {
  // 업데이트 좀 해
})

m.Post("/", func() {
  // 만들어봐
})

m.Put("/", func() {
  // 변경해봐
})

m.Delete("/", func() {
  // 없애버려!
})

m.Options("/", func() {
  // http 옵션 메소드
})

m.NotFound(func() {
  // 404 해결하기
})

루트들은 정의된 순서대로 매칭된다. 들어온 요구에 처음으로 매칭된 루트가 호출된다.

루트 패턴은 martini.Params service로 액세스 가능한 인자들을 포함하기도 한다:

m.Get("/hello/:name", func(params martini.Params) string {
  return "Hello " + params["name"]			// :name을 Params인자에서 추출
})

루트는 별표식(*)으로 매칭 될 수도 있습니다:

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 함수가 resopnse에 결과를 쓰지 않는이상 실행 될 거에요.
})

RootGroup은 루트들을 한 곳에 모아 정리하는데 유용합니다.

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)
})

핸들러에 미들웨어를 집어넣을 수 있는것과 같이, 그룹에도 미들웨어를 집어넣는 것이 가능합니다.

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)

서비스(Services)

서비스는 핸들러의 인수목록에 주입 될 수 있는 오브젝트들을 말합니다. 서비스는 글로벌 혹은 리퀘스트 레벨단위로 주입이 가능합니다.

글로벌 맵핑(Global Mapping)

마타니 인스턴스는 서비스 맵핑을 쉽게 하기 위해서 inject.Injector 인터페이스를 반형합니다:

db := &MyDatabase{}
m := martini.Classic()
m.Map(db) // 서비스가 모든 핸들러에서 *MyDatabase로서 사용될 수 있습니다.
// ...
m.Run()

리퀘스트 레벨 맵핑(Request-Level Mapping)

리퀘스트 레벨 맵핑은 핸들러안에서 martini.Context를 사용하면 됩니다:

func MyCustomLoggerHandler(c martini.Context, req *http.Request) {
  logger := &MyCustomLogger{req}
  c.Map(logger) // *MyCustomLogger로서 맵핑 됨
}

인터페이스로 값들 맵핑(Mapping values to Interfaces)

서비스의 강력한 기능중 하나는 서비스를 인터페이스로 맵핑이 가능하다는 것입니다. 예를들어, http.ResponseWriter를 재정의(override)해서 부가 기능들을 수행하게 하고 싶으시다면, 아래와 같이 핸들러를 작성 하시면 됩니다.

func WrapResponseWriter(res http.ResponseWriter, c martini.Context) {
  rw := NewSpecialResponseWriter(res)
  c.MapTo(rw, (*http.ResponseWriter)(nil)) // ResponseWriter를 NewResponseWriter로 치환(override)
}

정적파일 서빙(Serving Static Files)

martini.Classic() 인스턴스는 "public" 폴더안에 있는 파일들을 정적파일로써 자동으로 서빙합니다. 더 많은 폴더들은 정적파일 폴더에 포함시키시려면 martini.Static 핸들러를 이용하시면 됩니다.

m.Use(martini.Static("assets")) // "assets" 폴더에서도 정적파일 서빙.

미들웨어 핸들러(Middleware Handlers)

미들웨어 핸들러는 http request와 라우팅 사이에서 작동합니다. 미들웨어 핸들러는 근본적으로 다른 핸들러들과는 다릅니다. 사용방법은 아래와 같습니다:

m.Use(func() {
  // 미들웨어 임무 수행!
})

Handlers를 이용하여 미들웨어 스택들의 완전 컨트롤이 가능합니다. 다만, 이렇게 설정하시면 이전에 Handlers를 이용하여 설정한 핸들러들은 사라집니다:

m.Handlers(
  Middleware1,
  Middleware2,
  Middleware3,
)

미들웨어 핸들러는 로깅(logging), 허가(authorization), 인가(authentication), 세션, 압축(gzipping), 에러 페이지 등 등, http request의 전후로 실행되어야 할 일들을 처리하기 아주 좋습니다:

// API 키 확인작업
m.Use(func(res http.ResponseWriter, req *http.Request) {
  if req.Header.Get("X-API-KEY") != "비밀암호!!!" {
    res.WriteHeader(http.StatusUnauthorized)	// HTTP 401
  }
})

Next()

Context.Next()는 선택적 함수입니다. 이 함수는 http request가 다 작동 될때까지 기다립니다.따라서 http request 이후에 실행 되어야 할 업무들을 수행하기 좋은 함수입니다.

// log before and after a request
m.Use(func(c martini.Context, log *log.Logger){
  log.Println("request전입니다.")

  c.Next()

  log.Println("request후 입니다.")
})

Martini Env

마티니 핸들러들은 martini.Env 글로벌 변수를 사용하여 개발환경에서는 프로덕션 환경과는 다르게 작동하기도 합니다. 따라서, 프로덕션 서버로 마티니 서버를 배포하시게 된다면 꼭 환경변수 MARTINI_ENV=production를 세팅해주시기 바랍니다.

FAQ

미들웨어들을 어디서 찾아야 하나요?

깃헙에서 martini-contrib 프로젝트들을 찾아보세요. 만약에 못 찾으시겠으면, martini-contrib 팀원들에게 연락해서 하나 만들어 달라고 해보세요.

  • auth - 인증작업을 도와주는 핸들러.
  • binding - request를 맵핑하고 검사하는 핸들러.
  • gzip - gzip 핸들러.
  • render - HTML 템플레이트들과 JSON를 사용하기 편하게 해주는 핸들러.
  • acceptlang - Accept-Language HTTP 해더를 파싱 할 때 유용한 핸들러.
  • sessions - 세션 서비스를 제공하는 핸들러.
  • strip - URL 프리틱스를 없애주는 핸들러.
  • method - 해더나 폼필드를 이용한 HTTP 메소드 치환.
  • secure - 몇몇 보안설정을 위한 핸들러.
  • encoder - 데이터 렌더링과 컨텐트 타입을위한 인코딩 서비스.
  • cors - CORS 서포트를 위한 핸들러.
  • oauth2 - OAuth2.0 로그인 핸들러. 페이스북, 구글, 깃헙 지원.

현재 작동중인 서버에 마티니를 적용하려면?

마티니 인스턴스는 http.Handler 인터페이스를 차용합니다. 따라서 Go 서버 서브트리로 쉽게 사용될 수 있습니다. 아래 코드는 구글 앱 엔진에서 작동하는 마티니 앱입니다:

package hello

import (
  "net/http"
  "github.com/go-martini/martini"
)

func init() {
  m := martini.Classic()
  m.Get("/", func() string {
    return "Hello 세계!"
  })
  http.Handle("/", m)
}

포트와 호스트는 어떻게 바꾸나요?

마티니의 Run 함수는 PORT와 HOST 환경변수를 이용하는데, 설정이 안되어 있다면 localhost:3000으로 설정 되어 집니다. 좀더 유연하게 설정을 하고 싶다면, martini.RunOnAddr를 활용해 주세요.

  m := martini.Classic()
  // ...
  log.Fatal(m.RunOnAddr(":8080"))

라이브 코드 리로드?

ginfresh 가 마티니 앱의 라이브 리로드를 도와줍니다.

공헌하기(Contributing)

마티니는 간단하고 가벼운 패키지로 남을 것입니다. 따라서 보통 대부분의 공헌들은 martini-contrib 그룹의 저장소로 가게 됩니다. 만약 마티니 코어에 기여하고 싶으시다면 주저없이 Pull Request를 해주세요.

About

expresssinatra의 영향을 받았습니다.

마티니는 Code Gangsta가 디자인 했습니다.