Golang

Golang REST API 만들기

채우는중 2021. 8. 5. 23:24

오늘은 Golang으로 간단한 REST API를 만드는 방법을 쓸까 한다. 바로 시작하자

 

우선은 Directory를 하나 만들고 시작

mkdir rest

 

go module 등록

go mod init noah.io/ark/rest

 

main.go 생성

touch main.go

 

Directory 구조

tree
.
├── go.mod
└── main.go

 

main.go

package main


func main() {

}

 

정말 간단하게 만들거라 위 구조에서 변경되는 건 없을 듯하다.

 

http 패키지를 이용해 우선 서버를 띄워보자.

package main
import "net/http"


func main() {
	http.ListenAndServe(":8080", nil)
}

이렇게만 하면 포트 8080인 서버를 하나 올릴 수 있다.

 

여기에서 라우팅 작업을 해보자

package main
import "net/http"


func main() {
	http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
		wr.Write([]byte("hello"))
    })
	http.ListenAndServe(":8080", nil)
}

위와 같이 http패키지의 HandleFunc 함수를 이용하면 내가 원하는 경로를 함수와 연결시킬 수 있다.

 

그럼 간단한 유저 정보를 가지고 있는 구조체를 만들어 본격적으로 테스트를 진행해보자

package main

import (
	"encoding/json"
	"net/http"
)

var users = map[string]*User{}

type User struct {
	Nickname string `json:"nickname"`
	Email    string `json:"email"`
}

func main() {
	http.HandleFunc("/users", func(wr http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet: // 조회
			json.NewEncoder(wr).Encode(users) // 인코딩
		case http.MethodPost: // 등록
			var user User
			json.NewDecoder(r.Body).Decode(&user) // 디코딩

			users[user.Email] = &user

			json.NewEncoder(wr).Encode(user) // 인코딩
		}
	})
	http.ListenAndServe(":8080", nil)
}

소스코드를 위와 같이 변경했다. 기본 패키지인 http는 라우팅을 메서드 별로 따로 설정해주는 기능이 없어 함수 내부에서 메서드를 확인하여 GET인 경우는 조회를 POST인 경우는 등록하는 처리를 해주었다. 

 

우선 등록을 해주고

조회를 해보자

정상적으로 작동은 하지만 응답 값들이 다 일반 text로 넘어온다. Response Header에 Content-Type을 넣어 json 형식으로 변경해보자.

 

package main

import (
	"encoding/json"
	"net/http"
)

var users = map[string]*User{}

type User struct {
	Nickname string `json:"nickname"`
	Email    string `json:"email"`
}

// 4
func jsonContentTypeMiddleware(next http.Handler) http.Handler {
	
    // 들어오는 요청의 Response Header에 Content-Type을 추가
	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
		rw.Header().Add("Content-Type", "application/json")
        
        // 전달 받은 http.Handler를 호출한다.
		next.ServeHTTP(rw, r)
	})
}

func main() {
	// 1
	mux := http.NewServeMux()
    
    // 2
	userHandler := http.HandlerFunc(func(wr http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case http.MethodGet: // 조회
			json.NewEncoder(wr).Encode(users)
		case http.MethodPost: // 등록
			var user User
			json.NewDecoder(r.Body).Decode(&user)

			users[user.Email] = &user

			json.NewEncoder(wr).Encode(user)
		}
	})

	// 3
	mux.Handle("/users", jsonContentTypeMiddleware(userHandler))
	http.ListenAndServe(":8080", mux)
}
  1. 새로운 Mux를 만들고
  2. 기존에 만들어 놓은 HandleFunc 함수를 HandlerFunc 타입으로 변경 후
  3. 만들어놓은 미들웨어에 파라미터로 넘긴다.
  4. 요청 들어온 Response Header에 ContentType을 추가하고 전달받은 HandleFunc타입의 함수에 ReponseWriter와 Request를 넘겨준다.

 

위 과정을 마치면 아래와 같이 JSON형식으로 응답을 준다.

 

등록

회원정보 등록 이미지

 

조회

회원정보 조회 이미지

 

간단한 REST API를 만들어봤다.

 

다음 글은 gorilla/mux 모듈을 사용하여 위 소스를 정리해보도록 하겠다.