정상우
hELLO.
정상우
전체 방문자
384,511
오늘
130
어제
1,174
  • hELLO. (121)
    • 컴퓨터과학 (4)
      • 알고리즘 & 자료구조 (4)
    • 언어 & 프레임워크 (63)
      • Go (23)
      • PHP & Laravel (40)
    • 웹 (7)
    • 블록체인 (12)
      • 메인넷 (9)
      • 암호화폐 플랫폼 (3)
    • 포트폴리오 (10)
    • 칼럼 (20)
      • 에세이 (4)
      • 개발자스럽게 살기 (14)
      • 회고 (2)
    • 티스토리 (5)

블로그 메뉴

  • ⚡ 개발자 이력서
  • 🌟 깃허브
  • 💻 강의
  • ✨ 예제코드
  • ⭐ 브런치
  • 태그 클라우드
  • 방명록

공지사항

  • 2차 도메인을 설정했습니다 ✨

인기 글

  • JWT(JSON Web Token)의 개념부⋯
    2021.07.29
    JWT(JSON Web Token)의 개념부⋯
  • 'REST' 를 보다 'RESTful' 하게⋯
    2021.08.14
    'REST' 를 보다 'RESTful' 하게⋯
  • [Laravel] 라라벨 프레임워크⋯
    2021.06.10
    [Laravel] 라라벨 프레임워크⋯
  • 깃허브를 포트폴리오로 쓰려면⋯
    2021.12.25
    깃허브를 포트폴리오로 쓰려면⋯
  • 암호화폐 트레이딩 봇을 만들었⋯
    2021.05.12
    암호화폐 트레이딩 봇을 만들었⋯

태그

  • 개발
  • go
  • 블록체인
  • 프로그래머스
  • 포트폴리오
  • php
  • 코딩테스트
  • 라라벨
  • Algorithm
  • 개발 리뷰

최근 댓글

  • 고맙습니다 ~^^
    정상우
  • 오늘 블로그 만들었는데 검색하⋯
    엥뿌삐
  • 좋은 스킨 정말 감사드립니다.⋯
    이태홍
  • 고맙습니다 ㅎㅎ
    정상우
  • 제가 원하던 최고의 스킨입니다⋯
    _HEON

최근 글

  • 빠르게 성장하는 개발자의 세⋯
    2022.06.08
    빠르게 성장하는 개발자의 세⋯
  • 개발자와 엔지니어, 그 사이에서
    2022.05.10
    개발자와 엔지니어, 그 사이에서
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.03
    아임포트(Iamport)로 결제기능⋯
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.01
    아임포트(Iamport)로 결제기능⋯
  • [Laravel] 카페24 호스팅에 라⋯
    2022.03.29
    [Laravel] 카페24 호스팅에 라⋯

티스토리

hELLO · Designed By 정상우.
정상우

hELLO.

언어 & 프레임워크/Go

Go: 웹 서버 구축하기 (net/http, html/template)

2020. 12. 30. 17:08

WAS(Web Application Server)

Node.js 서버처럼 Go 언어로 만든 서버도 동적 컨텐츠를 처리하는 WAS(Web Application Server)로써 동작하게 만들 수 있다. 보통 앞에 NginX, Apache 와 같은 범용적인 http 서버를 앞에다가 두고 뒤에 별도로 WAS 를 실행시켜두는 것이 일반적인 구성일 것이다. 물론 Go 로 만든 서버를 직접 80 포트에 바인딩하는 것도 가능하지만 요청이 많아질 경우 과부하가 걸릴 가능성도 있어서 많은 트래픽이 발생하는 경우에는 권장하는 방법은 아니다.

 

이 포스트에서 말하는 웹 서버는 Go 언어로 만든 서버를 의미할 것이며 이러한 서버를 만드는 행위는 Node.js http 모듈을 사용하여 만드는 것만큼 상당히 단순하다고 볼 수 있다. 개인적으로 사용 편의성은 Node.js 보다 훨씬 더 좋은 듯하다.

net/http

http 패키지는 웹 서버를 구축하기 위한 도구들이 담겨있는 패키지다. http 패키지 문서에서 꽤나 많은 함수와 타입 목록들을 볼 수 있지만, 간단히 소스코드를 작성하여 살펴보면 다음과 같다.

package main

import (
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello, Go!"))
	})
	if err := http.ListenAndServe(":3000", nil); err != nil {
		log.Fatal(err)
	}
}
http.ResponseWriter 타입은 io.Writer 인터페이스를 충족하기 때문에 해당 인터페이스를 받는 함수나 메서드에 사용할 수 있다.

논리적 경로인 URL 의 루트인 / 경로에 대한 라우팅과 그에 대한 로직을 설정한다. http.ListenAndServe() 함수를 쓰면 서버를 시작할 수 있으며 시작하는 순간 블러킹되기 때문에 서버를 시작할 때 어떤 문제가 발생하지 않는 이상은 error 가 반환되지 않는다.

http.HandleFunc(), http.Handle()

요청을 핸들링 하기 위한 함수로는 http.HandleFunc() 도 있겠지만, http.Handle() 도 있다. http.HandleFunc() 의 경우 파라매터로 함수를 받지만, http.Handle() 의 경우 Handler 타입을 받는다. Handle 는 인터페이스이며 해당 인터페이스를 만족하기만 하면 요청을 핸들링할 수 있다.

http.Handler

$ go doc http.Handler
package http // import "net/http"

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

http.HandlerFunc

http.HandlerFunc 는 인터페이스가 아닌 타입이며 http.Handler 인터페이스를 만족한다.

$ go doc http.HandlerFunc
package http // import "net/http"

type HandlerFunc func(ResponseWriter, *Request)
    The HandlerFunc type is an adapter to allow the use of ordinary functions as
    HTTP handlers. If f is a function with the appropriate signature,
    HandlerFunc(f) is a Handler that calls f.

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)

따라서 해당 타입을 사용하면 http.Handle() 을 사용해서도 핸들러를 넘길 수 있게된다.

http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello, Go!"))
}))

html/template

html/template 를 사용하면 Content-Type: text/html 을 응답으로 반환할 수 있다. html/template 의 기반은 text/template 이며 둘은 패키지 이름은 같지만 패키지 경로가 다르므로 서로 다른 패키지임을 주의하자. html/template 패키지는 text/template 패키지에 비해 웹에서 사용할 수 있도록 이스케이프와 같은 보안요소를 제공한다.

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	tmpl, err := template.New("index").Parse("<h1>Hello, Go!</h1>")
	if err != nil {
		http.Error(
			w,
			http.StatusText(http.StatusInternalServerError),
			http.StatusInternalServerError)
	}
	if err = tmpl.Execute(w, nil); err != nil {
		http.Error(
			w,
			http.StatusText(http.StatusInternalServerError),
			http.StatusInternalServerError)
	}
})
error 처리가 다소 지저분해 보이긴 한다만, Go 의 에러처리 방식은 어플리케이션 관점에서 보면 더욱 견고하게 구성할 수 있도록 만들어준다.

템플릿에 데이터 넘기기

template.New() 함수를 호출하여 새로운 템플릿을 생성하고, HTML String 을 파싱하거나 template.ParseFiles() 메서드를 사용하여 html 파일도 파싱할 수 있다. template.Execute() 메서드의 두번째 파라매터로는 템플릿에 넘길 데이터를 줄 수 있다. 예를 들면 다음과 같이 템플릿을 만들고 데이터를 넘길 수 있다.

tmpl, _ := template.New("index").Parse("<h1>{{.}}</h1>")
tmpl.Execute(w, "Hello, Go!")

{{.}} 와 같이 사용하면 . 이 템플릿에 넘겨준 데이터로 변환된다. 조건문과 반복문도 사용이 가능하며 일반적인 사용법으로는 템플릿에 데이터를 넘길때 구조체의 객체를 넘기는 것이다. 이러한 템플릿의 사용법은 html/template 패키지의 문서에 가보면 자세히 알 수 있다.

    '언어 & 프레임워크/Go' 카테고리의 다른 글
    • Go: 변수 스코프와 블록
    • Go: recover() 를 사용하여 복구하기 [Effective Go]
    • Go: Switch 를 사용하여 타입 체크하기 (Reflection) [Effective Go]
    • Go: new vs make [Effective Go]
    go, html/template, http, 웹 서버
    정상우
    정상우
    과거의 배움으로 현재를 바꾸고 미래를 만듭니다. #25+2살 #INFJ #개발자 #브런치작가
    댓글쓰기
    다음 글
    Go: recover() 를 사용하여 복구하기 [Effective Go]
    이전 글
    Go: Switch 를 사용하여 타입 체크하기 (Reflection) [Effective Go]
    • 이전
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • ···
    • 23
    • 다음

    티스토리툴바