본문 바로가기
Programming Language/Go

[3] Go 웹 프레임워크 Gin

by Riverandeye 2020. 10. 3.

Gin은 Golang으로 작성된 웹 프레임워크로, Node로 치면 Express 같은 미들웨어 지향 API를 제공합니다.

Gin 이전에 martini라는 웹 프레임워크가 있었기 때문에 martini-like api 라고 하는데, 

오픈소스인 httprouter 를 도입하여 그 성능을 높였다고 합니다.

httprouter에 대한 세부 분석은 다음 기회에 다루겠습니다.

 

지원하는 핵심 기능들은 다음과 같습니다

- Radix tree 기반의 라우팅으로 메모리 소요가 적으며 reflextion이 필요 없어 API 성능이 예측 가능합니다.

- 미들웨어를 지원하여 개별 HTTP Request에 수행되는 비즈니스 로직을 분리할 수 있습니다.

- 요청에 대한 Panic 을 Recover하기 때문에 안정적인 서빙이 가능합니다.

- 요청의 Json을 Validate 할 수 있습니다. (와우!) 

- Route를 그룹화하여 효율적으로 관리할 수 있으며, nesting이 가능합니다.

- 미들웨어를 이용해 Error를 편리하게 관리할 수 있습니다. 

 

QuickStart

go mod를 이용하여 패키지를 설치하고, 이를 import 하여 실행해봅시다. 

 

go mod init "<패키지 이름>"
go get -u github.com/gin-gonic/gin 

 

이를 수행하면 다음과 같은 결과가 나타난다. 

 

gin 프레임워크와 관련된 dependency가 같이 설치됩니다

 

모듈 설치가 완료되면 main.go 파일을 생성한 후 다음을 작성합니다. 

 

package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // listen and serve on 0.0.0.0:8080
}

아주 단순한 코드 예시입니다. 이를 실행하기 위해서 다음을 터미널에 작성합니다. 

 

go run example.go

이후 loopback address 8080 포트로 접속하면 다음을 확인할 수 있습니다. 

 

환경변수 및 모드 지정 없이 실행할 경우 다음과 같은 디버깅 메시지가 등장합니다.
localhost:8080/ping 으로 요청시 다음과 같은 json이 반환됩니다.

 

관련된 예제도 이 링크를 통해 확인할 수 있습니다. 좋은 예제가 많아서 직접 시도해보면 금방 이해할 수 있을 것입니다. 

해당 예제들에 대해서 수행한 것 또한 추가적으로 기록할 계획입니다. 

 

테스트 코드 작성

main 함수가 다음과 같을 때 

package main

import "github.com/gin-gonic/gin"

func setupRouter() *gin.Engine {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})
	return r
}

func main() {
	r := setupRouter()
	r.Run(":8080")
}

 

개별 라우터에 대한 테스트 코드를 다음과 같이 작성할 수 있습니다. 

 

package main

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestPingRoute(t *testing.T) {
	router := setupRouter()

	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/ping", nil)
	router.ServeHTTP(w, req)

	assert.Equal(t, 200, w.Code)
	assert.Equal(t, "pong", w.Body.String())
}

 

라우터를 초기화하고, httptest 를 이용하여 Recorder를 선언 후 NewRequest를 생성하여 

router의 ServeHTTP 메소드를 이용하여 그 결과를 w에 저장합니다. 

해당 메소드를 거쳤을 때 예상되는 결과와 실제 반환된 값 w를 assert 를 이용하여 구성해줍니다.

테스트에 성공시 다음과 같은 결과가 나타납니다. 

 

main.go 의 테스트코드인 main_test.go 를 go test 로 실행하였을 때 나타나는 결과

 

구체적인 Golang의 테스트에 관해서는 개별적으로 다룰 계획입니다. 

 

Gin 프레임워크로 개발된 여러 편의성을 제공하는 서버들의 예시가 이 링크에 제공됩니다.

 

Reference

gin-gonic.com/docs/

 

댓글