단 13줄? Go(Golang)로 만들어보는 웹 서버! 생각보다 정말 쉽네요!

Go(Golang) 언어는 구글이 만들었다는 사실만으로도 호기심을 자극하는 프로그래밍 언어입니다. 최신 웹 서비스 개발 뿐만 아니라 시스템 소프트웨어 구축에도 적합한 언어이기도 한데요.

 

처음 공개 때부터 IT 업계가 떠들썩할 정도로 이목이 집중됐었죠. 현재는 트위치(Twitch), 우버(Uber), 구글(Google), 사운드 클라우드(SoundCloud), 페도라 코어 OS(Fedora CoreOS), 넷플릭스(Netflix), 드롭박스(Dropbox), 도커(Docker), 쿠버네티스(Kubernetes) 등 여러 유명 서비스와 프로젝트에서 'Go' 언어를 활용하고 있습니다.

 

Go 언어는 내장 패키지의 종류가 광범위하고 기능이 강력한 덕분에 웹 개발에서 활용하기에도 부족함이 없는데요. 이번 글에서는 Go(Golang) 언어로 기초적인 수준의 웹 서버를 만들어보겠습니다!

 

 

 
Go 언어로 웹 서버를
 
필요한 패키지 가져오기

 

러 패키지 가운데 net/HTTP 패키지가 웹 서버나 클라이언트를 만드는 데 필요한 모든 기능을 담고 있습니다. 웹 프로그래밍에서 활용하기에 좋은 유용한 함수도 여럿 포함하고 있네요.

'사용 선언'을 통해 패키지를 가져오려면 소스 코드 맨 윗줄에 아래 내용을 추가합니다.


       import "net/http" 
    

 

사이트를 열면 '방문 환영' 메시지를 표시할 코드에서 변수 대입이 쉽도록 문자열 형식 지정/처리 패키지인 fmt와 오류 처리를 위한 log 패키지도 사용 선언을 해보겠습니다. 사용 선언은 위와 같이 import "패키지 이름"을 여러 줄 나열하는 방식도 있고요. 아래처럼 import 문은 한 번만 입력하고 여러 패키지 이름을 소괄호로 묶어 선언하는 방식도 있습니다.


       import (
            "fmt"
            "log"
            "net/http"
       )
    

 

필요한 패키지를 가져왔다면 다음으로는 main 함수를 작성할 차례네요. 코드 입력 후에는 소스 파일을 .go 확장자를 붙여 저장하세요. 저는 server.go라는 이름의 파일로 저장했습니다. 이제 본격적으로 main 함수의 내용을 한 줄씩 입력하고 살펴보겠습니다! 

 

 

 
Golang으로 웹 서버를
 
Main 함수 작성

 

Go 프로그램의 코드를 실행하면 기본적으로 main 함수 안에 있는 내용을 실행합니다. 이름이 분명해서 알기가 쉽네요. 이제 웹 서버를 시작하고 요청을 처리하는 코드를 짜보겠습니다. 소스 코드에 아래의 내용을 추가로 입력해주세요. 다 입력하셨나요? 이제 한 줄씩 그 의미를 살펴보겠습니다!


       func main() {
           http.HandleFunc("/", index)
           log.Fatal(http.ListenAndServe(":8080", nil))
       } 
    

 

우선, 함수를 정의할 때 사용하는 func라는 단어로 main 함수를 정의합니다. Go 언어는 '여는 중괄호 {'의 위치와 관련하여 규칙이 엄격한데요. 이 때문에 중괄호의 위치가 함수 이름 아래쪽이 아닌 함수 이름 오른쪽 옆에 있는지 꼭 확인해야 합니다. {func main()의 아래쪽에 놓이게 하면 오류가 발생합니다.

 

main 함수의 첫 번째 코드는 최상위("/") 경로로 오는 모든 웹 요청을 http.HandlerFunc 형식 함수인 index 함수가 처리하도록 지정합니다. 즉, 사용자가 사이트에 접속하면 index라는 이름의 함수를 실행합니다!

 

두 번째 줄에서는 http.ListenAndServe 함수로 웹 서버를 시작합니다. 웹 서버 실행 후에는 http.ListenAndServe 함수의 첫 번째 인자 값으로 대입한 8080번 포트에서 외부에서 들어오는 HTTP 요청을 지속적으로 수신합니다.

 

참고로 함수의 두 번째 인자 값으로는 외부에서 누군가 접속할 때 이를 처리하기 위해 실행할 함수를 지정해줘야 하는데요. 앞서 http.HandlerFunc 함수를 통해 접속자가 사이트를 열면 index 함수를 호출하도록 이미 설정했기 때문에 null에 해당하는 nil을 대입해줍니다. Go 언어에서는 null 값을 nil로 표기합니다. 

 

덧붙여서 http.ListenAndServe 함수는 항상 오류 값을 반환합니다. 평소에는 지속해서 실행 중인 상태를 유지하다가 예기치 않은 오류가 발생할 때만 결과 값을 반환하기 때문인데요. 따라서, 오류가 발생할 경우 이를 처리할 수 있도록 http.ListenAndServe 함수 호출문을 log.Fatal 함수로 감싸줍니다. log.Fatal 함수는 실행하면 오류 내용을 메시지로 출력하고 프로그램을 완전히 종료합니다.

 

 

 
Go 언어로 웹 서버를
 
Index 함수 구현

 

Main 함수에서 사용자가 접속하면 index 함수를 호출하도록 설정했는데요. 아직 index 함수를 정의하지 않았죠. 클라이언트의 요청을 처리할 index 함수를 작성해볼까요. 아래에 있는 코드 내용을 그대로 입력해주세요!


       func index(w http.ResponseWriter, r *http.Request) {
           fmt.Fprintf(w, "안녕하세요! %s에 오신 것을 환영합니다!", r.URL.Path[1:])
       } 
    

 

index 함수는 http.ResponseWriter 형식(타입)과 http.Request 형인 두 가지 '매개변수'를 받고 있는데요. http.ResponseWriter 형식의 변수 w는 HTTP 서버의 응답과 관련된 모든 데이터를 담고 있고요. 이 객체 변수를 대상으로 '(메시지) 출력'을 하면 방문자인 클라이언트로 데이터(문장)를 전송합니다. http.Request형 변수 r은 클라이언트의 HTTP 요청과 관련된 정보를 담고 있습니다.

 

fmt 패키지의 Fprintf 함수텍스트 문자열을 표시하거나 조작하기 위해 사용하는 함수입니다. 위의 코드에서는 클라이언트의 요청에 대한 서버의 응답을 보여주기 위한 용도로 사용하고 있고요. 

 

마지막으로 Fprintf 함수의 인자 값 중 하나인 r.URL.Path는 방문자가 요청한 접속 주소(URL)에서 도메인(example.com)이나 IP 주소(232.2.34.56) 다음으로 나오는 '경로'를 반환합니다. 이를 테면, https://domain.com/exam1의 경우 /exam1을 반환하고요.

 

r.URL.Path의 뒷부분에 덧붙은 [1:]는 '경로(Path)의 첫 번째 글자에서 마지막 글자까지만 남긴다'는 의미입니다. 여기서 글자의 순서는 0, 1, 2, 3, 4...의 순서로 세는데요. https://domain.com/exam1r.URL.Path[1:]을 적용하면 경로의 첫 번째 글자인 'e'에서 마지막 글자인 '1'까지만 남겨서 최종 값은 'exam1'이 되고요. 결과적으로 0번째 글자이고 맨 앞 글자인 '/'는 제거가 됩니다.

 

이에 따라 사이트 방문자가 https://domain.com/CZV 주소로 들어가면 "안녕하세요! CZV에 오신 것을 환영합니다!"를, https://domain.com/OGN 주소로 접속하면 "안녕하세요! OGN에 오신 것을 환영합니다!"라는 메시지를 표시합니다.

 

 

 
Go 언어로 웹 서버 만들기
 
최종 코드는?

 

코드를 모두 작성하셨다면? Go(Golang) 언어로 만든 웹 서버를 실제로 실행하는 일만 남았네요! 작성을 마친 최종 코드는 아래와 같습니다. 😊

 


        package main
        import (
            "fmt"
            "log"
            "net/http"
        )
        func index(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "안녕하세요! %s에 오신 것을 환영합니다!", r.URL.Path[1:])
        }
        func main() {
            http.HandleFunc("/", index)
            log.Fatal(http.ListenAndServe(":8080", nil))
        }
    

 

Go 언어를 설치한 상태에서 '명령 프롬프트'나 '터미널'을 열고 go run server.go 명령을 실행하여 웹 서버를 시작하고요.

웹 브라우저에서 http://127.0.0.1:8080/Naverhttp://127.0.0.1:8080/Daum 주소로 들어가면 아래와 같은 화면이 나옵니다. 여기서 접속 주소의 Naver나 Daum 부분을 다른 단어로 바꿨을 때 그 단어가 화면에 잘 나온다면? 성공입니다! 축하드립니다!

 

 
Go 언어로 한 걸음 더
 
Go 언어로 웹 서버를!

 

Go 언어는 수 많은 기능을 빠짐 없이 꼼꼼히 챙겨 라이브러리 '패키지'로 마련해두고 있는데요. 덕분에 웹 프로그래밍 경험이 많지 않은 초보 개발자도 원하는 기능을 쉽게 구현할 수 있습니다. 기초적인 수준의 웹 서버는 코드 몇 줄 만으로도 금방 만드네요.

 

게다가 Go 언어는 테스팅을 위한 강력한 기능을 갖추고 있어 '애자일(Agile) 개발 방법론'을 실제로 적용하기에도 딱 알맞습니다. 애자일 방법론은 반복적인 개발과 더불어 팀간의 광범위한 협업을 바탕으로 하는 일련의 '소프트웨어 개발 전략' 인데요. 앞으로도 애자일 방법론과 Go 언어에 대해서 계속해서 다뤄보겠습니다! 😉

 

덧붙여서.. 웹 개발에 관심이 있는 분이라면 웹 개발에 유용한! 놓치기 아까운 크롬 확장 프로그램을 한 곳에 모아 정리한 효율이 2배로? 웹 개발에 필수! 크롬 확장 프로그램 12가지! 글도 확인해보세요!

 

최종 수정일:
서지스윈

서지스윈

IT와 기술을 이해하고, 유용한 소프트웨어를 발견하도록 돕고 싶습니다. 윈도우(Windows), 맥(macOS), 리눅스(Linux), 스마트폰 앱, 웹 서비스, 기획 시리즈물까지. 더 많은 것을 발견하고, 더 많은 것을 해보세요.