Golang - 웹 서버 - 2
🔥 RESTful API
웹 서버를 구축할떄의 기준점이라고 할수 있는 RESTful API를 활용한 서버를 공부하였습니다.
대부분 HTTP메서드를 다루는 방법에 대해서 학습이 진행되었습니다.
- RESTful API에 대한 정의가 뚜렷하지 않아서;;
🔨 RESTful API 서버 만들기
일단 기본적으로 Go의 내부 패키지를 활용하여 만들수도 있습니다.
하지만 번거로운 작업이 되기 떄문에 RESTful API를 쉽게 만들 수 있도록 지원해주는 gorilla/mux
패키지를 사용 해 보았습니다.
go get -u github.com/gorilla/mux
를 통해서 설치해 줍니다.
go mod, build
를 적용하여 모듈을 초기화 시켜주어야 합니다.
package main
import (
"encoding/json"
"net/http"
"sort"
"github.com/gorilla/mux"
)
type Student struct {
Id int
Name string
Age int
Score int
}
var students map[int]Student
var lastId int
func MakeWebHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/students", GetStudentListHandler).Methods("GET")
// 함수가 아니 라는 점을 유의
students = make(map[int]Student)
students[1] = Student{1, "aaa", 16, 87}
students[2] = Student{2, "bbb", 18, 98}
lastId = 2
return mux
}
type Students []Student
func (s Students) Len() int {
return len(s)
}
func (s Students) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s Students) Less(i, j int) bool {
return s[i].Id < s[j].Id
}
func GetStudentListHandler(w http.ResponseWriter, r *http.Request) {
list := make(Students, 0)
for _, student := range students {
list = append(list, student)
}
sort.Sort(list)
json.NewEncoder(w).Encode(list)
}
func main() {
http.ListenAndServe(":3000", MakeWebHandler())
}
천천히 한번 다루어 보겠습니다.
일단 기본적으로 main()함수가 먼저 작동을 하게 되기 떄문에 MakeWebHandler()
함수가 작동을 하게 됩니다.
그러면 이전에 학습했던것과는 다르게 NewRouter
가 사용이 가능하고 이를 활용하여 Router를 만들어 줍니다.
- 이전에는
NewServeMux
를 활용 하였지만 - 이번 방식은
Methods
를 따로 편하게 지정을 할수 없기 떄문에 이전에 설치한 외부 모듈을 활용하여 간단하게 구성을 합니다.
이후 경로를 설정해 주고 해당 경로에 해당하는 Http메서드를 지정해 줍니다.
- 이런 방식이면 해당 경로의 GET요청은 뒤에 따라오는 함수가 작동한다는 의미가 됩니다.
이후 데이터 값들을 입력해 줌으로써 준비가 끝납니다.
이 부분의 작동 방식에 대해서는 Youtube를 통해서 다루어 보겠습니다.
🔨 특정 데이터 반환하기 [Mux.vars]
이제 특정 Id에 해당하는 학생 데이터를 반환하는 핸들러를 만들어 보겠습니다.
package main
import (
"encoding/json"
"fmt"
"net/http"
"sort"
"strconv"
"github.com/gorilla/mux"
)
type Student struct {
Id int
Name string
Age int
Score int
}
var students map[int]Student
var lastId int
func MakeWebHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/students", GetStudentListHandler).Methods("GET")
mux.HandleFunc("/students/{id:[0-9]+}", GetStudentHandler).Methods("GET")
students = make(map[int]Student)
students[1] = Student{1, "aaa", 16, 87}
students[2] = Student{2, "bbb", 18, 98}
lastId = 2
return mux
}
type Students []Student
func (s Students) Len() int {
return len(s)
}
func (s Students) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s Students) Less(i, j int) bool {
return s[i].Id < s[j].Id
}
func GetStudentListHandler(w http.ResponseWriter, r *http.Request) {
list := make(Students, 0)
for _, student := range students {
fmt.Println(student)
list = append(list, student)
}
sort.Sort(list)
json.NewEncoder(w).Encode(list)
}
func GetStudentHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) //id값을 가져오는 방법
fmt.Println(vars)
id, _ := strconv.Atoi(vars["id"])
student, ok := students[id]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(student)
}
func main() {
http.ListenAndServe(":3000", MakeWebHandler())
}
특정 데이터를 가져올떄 사용을 할수 있는 방법 입니다.
mus.Vars
에 인자를 넣어줌으로써 들어오는 데이터를 확인이 가능하고 이후 students부분에서 동일한 Id값이 있는지를 확인함으로써 작동이 됩니다.
- 쿼리와는 다른 방식 입니다.
🔨 데이터 추가 [post]
드디어 post요청을 하는 방법 입니다.
전체 코드보다는 추가해야할 코드를 적음으로써 다루어 보겠습니다.
일단 핸들러를 추가해 줍니다.
mux.HandleFunc("/student", PostStudentHandler).Methods("POST")
그후 핸들러에 추가된 함수를 추가해 줍니다.
func PostStudentHandler(w http.ResponseWriter, r *http.Request){
var student Student
err := json.NewDecoder(r.Body).Decode(&student)
if err != nil{
w.WriteHeader(http.StatusBadRequest)
return
}
lastId++
student.Id = lastId
students[lastId] = student
w.WriteHeader(http.StatusCreated)
}
POST요청이기 떄문에 들어오는 데이터를 담고 이후 변수값에 추가해 주는 방법으로 작동을 하게 됩니다.
🔨 데이터 삭제 [Delete]
그럼 반대로 삭제하는 방법에 대해서 다루어 보겠습니다.
먼저 핸들러를 추가해 줍니다.
mux.HandleFunc("/students/{id:[0-9]+}", DeleteStudentHandler).Methods("DELETE")
이후 마찬가지로 사용할 함수를 추가해 줍니다.
func DeleteStudentHandler(w http.ResponseWriter, r *http.Request){
vars:=mux.Vars(r)
id, _ :=strconv.Atoi(vars["id"])
_,ok := students[id]
if !ok{
w.WriteHeader(http.StatusNotFound)
return
}
delete(students, id)
w.WriteHeader(http.StatusOK)
}
🔨 전체 코드
package main
import (
"encoding/json"
"fmt"
"net/http"
"sort"
"strconv"
"github.com/gorilla/mux"
)
type Student struct {
Id int
Name string
Age int
Score int
}
var students map[int]Student
var lastId int
func MakeWebHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/students", GetStudentListHandler).Methods("GET")
mux.HandleFunc("/students/{id:[0-9]+}", GetStudentHandler).Methods("GET")
mux.HandleFunc("/student", PostStudentHandler).Methods("POST")
mux.HandleFunc("/students/{id:[0-9]+}", DeleteStudentHandler).Methods("DELETE")
students = make(map[int]Student)
students[1] = Student{1, "aaa", 16, 87}
students[2] = Student{2, "bbb", 18, 98}
lastId = 2
return mux
}
type Students []Student
func (s Students) Len() int {
return len(s)
}
func (s Students) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s Students) Less(i, j int) bool {
return s[i].Id < s[j].Id
}
func DeleteStudentHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, _ := strconv.Atoi(vars["id"])
_, ok := students[id]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
delete(students, id)
w.WriteHeader(http.StatusOK)
}
func PostStudentHandler(w http.ResponseWriter, r *http.Request) {
var student Student
err := json.NewDecoder(r.Body).Decode(&student)
fmt.Println(r.Body)
if err != nil {
fmt.Println("에러 발생!!")
w.WriteHeader(http.StatusBadRequest)
return
}
lastId++
student.Id = lastId
students[lastId] = student
w.WriteHeader(http.StatusCreated)
}
func GetStudentListHandler(w http.ResponseWriter, r *http.Request) {
list := make(Students, 0)
for _, student := range students {
fmt.Println(student)
list = append(list, student)
}
sort.Sort(list)
json.NewEncoder(w).Encode(list)
}
func GetStudentHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) //id값을 가져오는 방법
fmt.Println(vars)
id, _ := strconv.Atoi(vars["id"])
student, ok := students[id]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(student)
}
func main() {
http.ListenAndServe(":3000", MakeWebHandler())
}
코드에 대한 실습 및 작동 원리는 Youtube에 정리 하였습니다!
Author And Source
이 문제에 관하여(Golang - 웹 서버 - 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jjimgo/Golang-웹-서버-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)