Go Lang 웹 프레임워크 기초 - Gin 체험하기 (7) 단일 기사 링크 제작하기
해당 튜토리얼은 'Building Go Web Applications and Microservices Using Gin'의 내용을 번역하며 개인적으로 정리한 것입니다.
이번 시간에는 각 기사(Article)를 선택할 때 표시될 수 있는 핸들러와 템플릿을 추가하도록 하겠습니다.
1. 라우터 설정
이전 라우터와 동일한 방식으로 단일 기사에 대한 요청을 처리하기 위해 새 라우터를 설정하도록 합니다. 모든 기사들의 핸들러는 동일하겠지만, 각 기사별 URL은 다를 수 있다는 점을 고려해야 합니다. Gin을 사용하면 다음과 같이 경로 매개변수를 정의해서 해당 조건을 처리할 수 있습니다.
router.GET("/article/view/:article_id", getArticle)
이 라우터는 위 경로와 맞는 요청에 대해 라우터를 일치시키고, 라우터의 마지막 부분 값을 article_id 에 저장하도록 합니다. 이 라우터는 getArticle을 정의합니다.
이로 인해 업데이트된 routes.go 파일의 코드는 다음과 같습니다.
▶ routes.go
// routes.go
package main
func initializeRoutes() {
// 인덱스 라우터 처리(Handle)
router.GET("/", showIndexPage)
// /article/view/some_article_id 부분에 대한 GET 요청 처리
router.GET("/article/view/:article_id", getArticle)
}
2. 뷰 템플릿 작성
우리는 templates/article.html 이라는 이름으로 새로운 템플릿을 생성할 필요가 생겼습니다. 해당 파일은 index.html 템플릿과 유사한 방법으로 만들 수 있습니다. 다만 이 경우 기사 목록이 포함된 Payload 변수 대신 단일의 기사가 포함될 것입니다.
▶ article.html
<!--article.html-->
<!-- header.html 템플릿을 이 위치에 포함시킵니다 -->
{{ template "header.html" .}}
<!--기사 제목을 표시합니다-->
<h1>{{.payload.Title}}</h1>
<!--기사 본문 내용을 표시합니다-->
<p>{{.payload.Content}}</p>
<!-- footer.html 템플릿을 이 위치에 포함시킵니다 -->
{{ template "footer.html" .}}
3. 라우터 핸들러 생성
기사 페이지 핸들러 getArticle은 다음의 작업을 수행합니다.
3-1. 표시할 기사의 ID를 추출합니다
알맞는 기사를 가져와 표시하려면 먼저 Context에서 ID를 추출해야 합니다. 추출하는 방법은 다음과 같습니다.
c.Param("article_id")
여기서의 c 는 Gin을 사용할 때 라우터 핸들러의 매개변수인 Gin Context를 의미합니다.
3-2. 기사 가져오기
이 부분은 models.article.go 파일에 정의된 getArticleByID() 함수를 통해 수행할 수 있습니다.
article, err := getArticleByID(articleID)
models.article.go에 포함된 getArticleByID 함수는 다음과 같습니다
func getArticleByID(id int) (*article, error) {
for _, a := range articleList {
if a.ID == id {
return &a, nil
}
}
return nil, errors.New("기사를 찾을 수 없습니다")
}
이 함수는 기사 목록을 반복하고 ID가 전달된 ID와 일치하는 기사를 반환합니다. 일치하는 기사가 없으면 오류를 반환합니다.
3-3. 기사를 전달하는 article.html 템플릿을 렌더링합니다
다음과 같은 코드를 사용해 수행할 수 있습니다.
c.HTML(
// ----- HTTP Status를 200(OK)로 설정합니다 ------ //
http.StatusOK,
// ----- article.html 템플릿을 사용합니다 ------ //
"article.html",
// ---- 페이지에서 사용하는 데이터를 전달합니다 ----- //
gin.H{
"title": article.Title,
"payload": article,
},
)
위의 코드를 포함하여 업데이트된 handlers.article.go 파일은 다음과 같이 구성될 것입니다.
▶ handlers.article.go
// handlers.article.go
package main
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
func showIndexPage(c *gin.Context) {
articles := getAllArticles()
// 템플릿 렌더링을 위해 Context의 HTML 메소드 호출
c.HTML(
// ----- HTTP Status를 200(OK)로 설정합니다 ------ //
http.StatusOK,
// ----- article.html 템플릿을 사용합니다 ------ //
"index.html",
// ---- 페이지에서 사용하는 데이터를 전달합니다 ----- //
gin.H{
"title": "Home Page",
"payload": articles,
},
)
}
func getArticle(c *gin.Context) {
// ----- 기사 ID가 유효한지 확인합니다 ----- //
if articleID, err := strconv.Atoi(c.Param("article_id")); err == nil {
// ----- 기사가 존재하는지 확인합니다 ----- //
if article, err := getArticleByID(articleID); err == nil {
// Call the HTML method of the Context to render a template
c.HTML(
http.StatusOK,
"article.html",
gin.H{
"title": article.Title,
"payload": article,
},
)
} else {
// ---- 기사를 찾을 수 없는 경우 오류와 함께 중단합니다 ---- //
c.AbortWithError(http.StatusNotFound, err)
}
} else {
// ---- URL에 잘못된 기사 ID가 지정된 경우 오류와 함께 중단합니다 ---- //
c.AbortWithStatus(http.StatusNotFound)
}
}
이제 어플리케이션을 Build하고 실행시켜봅니다. http://localhost:8080/article/view/1 에 접속하면 다음과 같은 화면이 뜨게됩니다.
'IT > Develop' 카테고리의 다른 글
Windows CMD에서 Linux처럼 ls 명령어 사용하기 (0) | 2021.09.17 |
---|---|
How to Node.js, NPM version upgrade (0) | 2021.09.15 |
[BOJ 2884번 알람 시계] Go Lang 문제풀이 (0) | 2021.09.06 |
[ BOJ 14681번 사분면 고르기 ] Go Lang 문제풀이 (0) | 2021.09.05 |
AWS 따라하기 - AWS EC2 시작하기! (0) | 2021.09.03 |