이 섹션에서는 요청 헤더에 따라 애플리케이션이 HTML, JSON 또는 XML 형식으로 응답 할 수 있도록 애플리케이션을 약간 리팩터링합니다.
1. 재사용 가능한 함수 만들기
Route Handler에서 지금까지는 Gin의 컨텍스트 중 HTML을 사용했습니다. 항상 HTML페이지를 보여줄 때는 괜찮지만, 요청에 따라 응답 형식을 변경하고 싶을 때에는 렌더링을 처리하는 단일 함수로 리팩토링해야합니다(?). 이렇게 함으로써 Route Handler는 유효성 검사(validation) 및 데이터 추출(data fetching)에 집중하도록 할 수 있습니다.
Route Handler는 응답 형식에 관계없이 동일한 유효성 검사, 데이터 추출 및 처리를 수행해야합니다. 이 부분이 완료되면 데이터를 사용하여 원하는 형식의 응답을 생성 할 수 있습니다. HTML 응답이 필요한 경우 데이터를 HTML 템플릿에 전달하고, JSON 응답이 필요한 경우이 데이터를 JSON으로 변환, XML에서도 마찬로 데이터를 보내줄 수 있습니다.
main.go 파일 내부에 모든 Route Handler가 사용할 render 함수를 만들겠습니다. 이 함수는 request의 Accept header를 참조하여 rendering을 처리할 것입니다.
Gin에서는 라우트 핸들러에 전달 된 Context 객체에 Request라는 필드가 포함됩니다. This field contains the header field which contains all the request headers. Get 메소드를 를 이용하여 Header로부터 Accept header를 다음과 같이 추출할 수 있습니다.
// c is the Gin Context
c.Request.Header.Get("Accept")- application/json 으로 설정하면 함수가 JSON을 렌더링합니다.
- application/xml 으로 설정하면 함수가 XML을 렌더링하고
- 이것이 다른 것으로 설정되거나 비어 있으면 함수는 HTML을 렌더링합니다.
main.go에 render 함수를 아래와 같이 추가합니다.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
var router *gin.Engine
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
router.GET("/", showIndexPage)
router.GET("/article/view/:article_id", getArticle)
router.Run()
}
func render(c *gin.Context, data gin.H, templateName string) {
switch c.Request.Header.Get("Accept") {
case "application/json":
// Respond with JSON
c.JSON(http.StatusOK, data["payload"])
case "application/xml":
// Respond with XML
c.XML(http.StatusOK, data["payload"])
default:
// Respond with HTML
c.HTML(http.StatusOK, templateName, data)
}
}
2. 유닛 테스트를 통한 Route Handler 요구사항 정의 =>생략...
3. Route Handler 업데이트
기존의 c.HTML방법을 render 함수로 바꿔주기만 하면 됩니다.
<기존>
func showIndexPage(c *gin.Context) {
articles := getAllArticles()
// Call the HTML method of the Context to render a template
c.HTML(
// Set the HTTP status to 200 (OK)
http.StatusOK,
// Use the index.html template
"index.html",
// Pass the data that the page uses
gin.H{
"title": "Home Page",
"payload": articles,
},
)
}<변경>
func showIndexPage(c *gin.Context) {
articles := getAllArticles()
// Call the render function with the name of the template to render
render(c, gin.H{
"title": "Home Page",
"payload": articles}, "index.html")
}
JSON 형식으로 Article List 추출
JSON테스트를 위해새로 어플리케이션을 빌드한 후 아래를 실행합니다.
curl -X GET -H "Accept: application/json" http://localhost:8080/
다음과 같은 응답을 반환해야합니다.
[{"id":1,"title":"Article 1","content":"Article 1 body"},{"id":2,"title":"Article 2","content":"Article 2 body"}]
XML 형식으로 Article 추출
XML 테스트를 위해 아래의 명령어를 실행합니다.
curl -X GET -H "Accept: application/xml" http://localhost:8080/article/view/1
다음과 같은 응답을 반환해야합니다.
<article><ID>1</ID><Title>Article 1</Title><Content>Article 1 body</Content></article>
4. Application 테스트
이제 우리가 작성한 테스트를 실행하고 결과를 확인해 보겠습니다. 프로젝트 폴더에서 다음 명령을 실행합니다.
go test -v
이 명령을 실행하면 아래와 유사한 결과가 나타납니다.
=== RUN TestShowIndexPageUnauthenticated [GIN] 2016/06/14 - 19:07:26 | 200 | 183.315µs | | GET / --- PASS: TestShowIndexPageUnauthenticated (0.00s) === RUN TestArticleUnauthenticated [GIN] 2016/06/14 - 19:07:26 | 200 | 143.789µs | | GET /article/view/1 --- PASS: TestArticleUnauthenticated (0.00s) === RUN TestArticleListJSON [GIN] 2016/06/14 - 19:07:26 | 200 | 51.087µs | | GET / --- PASS: TestArticleListJSON (0.00s) === RUN TestArticleXML [GIN] 2016/06/14 - 19:07:26 | 200 | 38.656µs | | GET /article/view/1 --- PASS: TestArticleXML (0.00s) === RUN TestGetAllArticles --- PASS: TestGetAllArticles (0.00s) === RUN TestGetArticleByID --- PASS: TestGetArticleByID (0.00s) PASS ok github.com/demo-apps/go-gin-app 0.084s
이 출력에서 볼 수 있듯이이 명령은 우리가 작성한 모든 테스트를 한번에 실행하며,이 경우 애플리케이션이 의도 한대로 작동하고 있음을 나타냅니다. 출력을 자세히 살펴보면 Go가 경로 핸들러를 테스트하는 과정에서 HTTP 요청을 수행했음을 알 수 있습니다.
이렇게 Gin Framework에 대한 강좌 따라하기를 수행해보았는데요, 마지막 JSON/XML 부분과 최종 테스트 부분은 아직 정확히 테스트는 못해보고 그냥 자료 번역 수준으로 올려놓습니다. 나중에라도 익숙해지면 해보려구요. 혹시라도 참고가 되시면 좋겠습니다.
그럼 이만~~~
'Programming > Golang' 카테고리의 다른 글
| Go언어 - Fyne 한글 폰트 설정 (2) | 2021.01.01 |
|---|---|
| Go언어 - Lorca GUI CSS 적용하기 (0) | 2020.12.18 |
| Go언어 - Gin Framework(4강 개별 Article 화면 구성) (0) | 2020.12.15 |
| Go언어 - Gin Framework(3강 Article List) (0) | 2020.12.14 |
| Go언어 - Gin Framework (2강 HTML Template 구성) (0) | 2020.12.13 |