본문 바로가기
Go/Go Web Programming

[Go Web programming] 001.Go로 시작하는 웹서버 | 데인트리 라이브러리

by 데인트리 2021. 6. 6.

 

 

이 페이지에서는 웹서버의 개념과 Go로 작성한 간단한 웹서버 코드를 소개한다.

 

 

 

 

 

Go Web Programing 카테고리는 Go 언어를 어느정도 이해하고 있고(특히 인터페이스 부분), Go 언어를 사용한 웹개발에 관심이 있는 분들이 천천히 읽기 좋도록 작성할 예정이다.

 

사우 셩 창(Sau Sheong Chang)의 Go 웹프로그래밍[BJ리퍼블릭/2016] 책이 많은 도움이 되었다. 책의 정보와 Go 공식문서의 예제를 통해 직접 학습용 소스를 작성하여 테스트를 여러 번 수행하였다. 글은 그 과정에서 얻은 정보를 최대한 쉽게 작성하려고 노력했다.

 

샤우 셩 창의 Github: https://github.com/sausheong/gwp

Go 공식문서의 패키지 정보: https://golang.org/pkg/

 

 

 

1. 웹 서버(Web Server)

서버(Server)는 무언가를 주는 역할을 한다. 제공하다라는 뜻을 가진 'Serve'라는 단어는 우리에게 꽤 익숙한데, 소비자에게 가치를 제공하는 서비스(Service), 구기종목에서 상대팀에 공을 넘기는 서브(Serve)와 식당에서 음식을 제공하는 행위를 홀서빙(Serving)이라고도 부른다. 즉 서버를 정의하면 '특정 요청에 따른 응답을 제공하는 것'이다. 그리고 서버에게 요청을 하는 행위자를 클라이언트라고 부른다.

 

그러면 서버는 무엇을 제공할까? 어떤 정보를 제공하는지에 따라 서버를 분류할 수 있다. 대표적으로 파일 서버, 메일 서버, 웹 서버 등이 있는데, 예를 들어 파일 서버는 어떤 파일에 대한 다운로드/업로드 요청 시 해당 요청에 알맞은 파일을 제공하거나 업로드 한다. 그리고 해당 서버들은 인터넷에서 정보를 주고받기 위해 특정 프로토콜(규약,약속)이 존재한다. 예를 들어 메일을 보낼 때 수신인, 발신인, 참조, 메일내용 등의 항목을 채우는 것처럼, 다른 두 개의 매체가 정보를 주고받기 위해서는 프로토콜이 필수로 필요하다. 웹 서버는 HTTP 프로토콜이 가장 대표적으로 사용된다. 정리하자면 웹 서버는 HTTP 프로토콜로 작성된 요청에 대한 응답을 제공하는 프로그램(소프트웨어)이다.

 

어떤 정보를 제공하는지에 따라 서버의 종류와 프로토콜이 다르다.

 

일반적으로 서버(Server)는 프로그램이 실행되는 하나의 고성능 하드웨어(컴퓨터)를 의미한다. 서버는 하나의 컴퓨터이기 때문에 여러 프로그램을 실행할 수 있는데, 이 프로그램 중 클라이언트에 대한 서비스를 제공하는 프로그램을 웹서버, 메일서버, 파일서버로 부른다. 하지만 서버라는 단어를 지칭할때 하드웨어, 소프트웨어의 경계가 명확한 것은 아니다. 보통은 혼합해서 사용하는 것 같다.

 

2. 간단한 웹서버 예제

https://github.com/daintree-henry/studygo/blob/main/200.Web/201.SimpleWebHandler/main.go

 

daintree-henry/studygo

Go 스터디 자료입니다. Contribute to daintree-henry/studygo development by creating an account on GitHub.

github.com

package main

import (
	"fmt"
	"net/http"
)

type indexHandler struct{} //(2)

func (i *indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Index Page")
}

func main() {
	index := indexHandler{}

	http.Handle("/", &index) //(3)

	http.ListenAndServe(":8080", http.DefaultServeMux) //(1)
	//http.ListenAndServe(":8080", nil) //기본값이 DefaultServeMux이다.
}

Go 언어를 활용해 서버를 실행시킬 수 있는 코드이다.

웹 서버를 구현하려면 net/http 패키지를 사용한다. (https://golang.org/pkg/net/http/)

 

 

(1) main함수에서 http.ListenAndServe(addr string, handler Handler) 함수를 호출하면, 데몬 형태로 특정 포트에서 HTTP요청을 받아들이는 웹 서버 프로그램이 실행된다. 첫 번째 파라미터로 요청을 받아들일 포트를 지정하고, 두 번째 파라미터로 멀티플렉서를 지정한다. 두 번째 파라미터에 nil을 입력해도 DefaultServeMux가 사용되기 때문에 어떤 값을 지정해도 무방하다. 멀티플렉서는 웹서버에서 특정 경로에 대한 요청(URL)별로 다른 핸들러를 호출한다.

 

(2) indexHandler에 대한 정의 부분이다. indexHandler는 핸들러인데, 핸들러는 요청에 대한 응답을 수행한다. ServeHTTP 메서드를 통해 "Index Page"라는 응답을 제공할 것을 정의하고 있다. 이 indexHandler 타입은 ServeHTTP함수를 정의하여 Handler 인터페이스를 구현하였고, 따라서 (3)에서 http.Handle(pattern string, handler Handler) 함수를 통해 멀티플렉서에 연결이 가능하다. 핸들러와 멀티플렉서는 002 포스팅에서 좀 더 자세히 다룰 것이다.

 

(3) http.Handle(pattern string, handler Handler) 함수는 "/"경로에 대한 요청에 indexHandler를 지정해 DefaultServeMux에 연결한다.

 

 

정리하자면 (1)에서 웹서버를 실행하며 사용할 포트와 멀티플렉서를 지정했고, (2)에서 "Index Page"응답을 반환하는 핸들러를 정의한 다음, (3)에서 http.Handle 함수를 통해 멀티플렉서에 경로와 핸들러를 연결하는 구조로 웹 서버 코드가 구성되는 것을 알 수 있다. 

 

좀 더 직관적인 이해 그림으로 표현해 보았다. 해당 그림을 통해 구조를 파악하고 다시 위의 코드를 살펴보면 더 이해가 쉬울 것이다.

 

[실행 결과]

(1) $ go run . 로 코드를 실행한다.

(2) 웹 브라우저에서 http://localhost:8080으로 접속한다.

(3) Index Page라는 문자열이 출력된다.

 

[연습]

위의 코드에 핸들러를 하나 더 추가하여 "/about" 경로에 대한 요청에 "About Page"를 반환하도록 코드를 작성한다. 위의 예제만 활용해서 작성이 가능하다.

 

 

 

 

 

내용에 오류가 있거나 질문이 있으면 댓글로 소통해주세요

언제나 환영합니다

 

댓글