Files

3.8 KiB

2단계: HTTP & Gin 웹 서버 상세 가이드

학습 로드맵으로 돌아가기

이 문서는 grpccanary 프로젝트의 2단계: HTTP & Gin 웹 서버에 대한 이론적 배경과 코드 구조를 설명합니다.

HTTP(Hypertext Transfer Protocol)는 클라이언트와 웹 서버가 웹에서 리소스를 교환하기 위해 정의한 규약입니다. Go 언어에서는 전통적인 net/http 표준 라이브러리 외에도, 성능이 우수하고 사용하기 쉬운 서드파티 웹 프레임워크인 Gin-gonic을 주로 사용하여 RESTful API를 신속하게 설계합니다.


1. REST API와 HTTP 통신

REST(Representational State Transfer)는 웹 상의 리소스를 HTTP 메서드(GET, POST, PUT, DELETE 등)와 URI 경로를 활용해 상태를 제어하는 아키텍처 스타일입니다.

  • JSON 데이터 연계: 대다수의 HTTP REST API는 클라이언트와 데이터를 송수신할 때 데이터 교환 바디(Body)에 텍스트 기반의 JSON 포맷을 담아 통신합니다.
  • 유연성과 한계: JSON을 사용한 HTTP 통신은 어떤 기기에서나 쉽게 파싱이 가능해 클라이언트-서버 통신에 널리 쓰이지만, 엄격한 스키마 정의가 없어 타입 런타임 오류가 발생하기 쉽고 바이너리 통신에 비해 무겁다는 특징이 있습니다.

2. Gin 웹 프레임워크

Go 진영에서 대표적으로 사랑받는 웹 프레임워크 중 하나로, 빠른 속도와 미들웨어 체인 구성, 편리한 라우팅 그룹 관리 기능을 지원합니다.

gin.Default() vs gin.New()

  • gin.New(): 미들웨어가 탑재되지 않은 완전히 빈 라우터 엔진을 인스턴스화합니다. 성능에 민감하고 로깅이나 복구 미들웨어를 직접 커스텀할 때 활용합니다.
  • gin.Default(): 기본적인 로깅 미들웨어(gin.Logger())와 오류 복구 미들웨어(gin.Recovery())가 사전 탑재된 상태로 기동되어 보통의 개발 시에 편리하게 사용됩니다.

3. 실습 코드 분석 (lib/httpentity/server.go)

저장소의 server.go 파일에는 Gin 라우터를 구성하고 API 서버와 정적 웹 서빙을 혼합하여 라우팅을 우회 처리하는 설계 패턴이 주석 상태로 존재합니다.

3.1 라우터 엔진 분리 및 통합 핸들링

apiEngine := gin.New()
apiGroup := apiEngine.Group("/api")
{
	apiGroup.GET("/randomNumber", GET_RandomNumber)
	apiGroup.GET("/randomPassword", GET_RandomPassword)
	apiGroup.GET("/randomDate", GET_RandomDate)
}

staticEngine := gin.New()
staticEngine.Static("/", "./web")
  • API 그룹 분리: /api로 들어오는 모든 요청을 apiEngine이 받아서 각각 /randomNumber, /randomPassword 등의 실제 비즈니스 로직 핸들러로 전달하게 설계되어 있습니다.
  • 정적 서빙: 그 외의 요청에 대해서는 ./web 경로의 정적 파일(HTML, CSS, JS)을 제공하기 위한 staticEngine을 별개 구성합니다.
  • 단일 엔트리 우회: 메인 엔진(r)은 전방위 라우팅 /*any를 구성하여, 경로 패턴에 /api가 들어있으면 API 엔진에 역할을 위임하고, 그렇지 않으면 정적 파일 서버로 포워딩합니다.

3.2 JSON 디코딩 및 API 핸들러

func GET_RandomNumber(c *gin.Context) {
	dec := json.NewDecoder(c.Request.Body)
	obj := map[string]interface{}{}
	dec.Decode(&obj)

	response := map[string]interface{}{
		"value": 10,
	}

	c.JSON(http.StatusOK, response)
}
  • c.Request.Bodyjson.NewDecoder로 받아서 맵에 디코딩하여 요청 매개변수(시드 등)를 취득합니다.
  • 비즈니스 연산 후 c.JSON() 함수를 통해 원하는 응답 구조를 손쉽게 클라이언트에 JSON 문자열 형태로 내보내 줍니다.