이 섹션에서는 요청 헤더에 따라 애플리케이션이 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 |