티스토리 뷰
Routing
이번에는 좀더 Routing 에 대해서 깊이 있게 알아보자.
HTTP Method
웹은 기본적으로 CRUD를 위한 GET, POST, PUT, DELETE 를 제공한다.
그 밖에도 HEAD, PATHCH 등 다양한 메소드를 제공한다.
이전 예제에서 핸들러를 단순 등록하면 모든 Method 를 받아 들일 수 있다.
그러나 이는 좋은 방법이 아니며, 용도에 맞는 메소드를 지정하여 endpoint 를 열어주는 것이 필요하다.
Method 이용하기.
main.go 에 다음과 같이 내용을 변경해보자.
package main
import (
"fmt"
"html"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HelloWorld).Methods("GET")
r.HandleFunc("/path/value", ResponsePath).Methods("GET")
r.HandleFunc("/users", CreateUser).Methods("POST")
r.HandleFunc("/users", UpdateUser).Methods("PUT")
r.HandleFunc("/users", DeleteUser).Methods("DELETE")
r.HandleFunc("/my", CallMy).Methods("POST", "PUT")
http.Handle("/", r)
fmt.Println("Server start on port: ", 8080)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
}
func ResponsePath(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Your request path is :%q", html.EscapeString(r.URL.Path))
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "CreateUser :")
}
func UpdateUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "UpdateUser :")
}
func DeleteUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "DeleteUser :")
}
func CallMy(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Call My Page :")
}
/users 경로에 대해서 POST, PUT, DELETE 메소드를 각자 지정하고, 필요한 핸들러를 작성해 주었다.
위처럼 Methods() 함수를 이용하여 다양한 요청을 처리할 수 있다.
/my 경로에 대해서는 POST, PUT 2개의 메소드만 허용하도록도 설정해 보았다.
테스트 하기.
✗ curl http://localhost:8080/users -X POST
CreateUser :
✗ curl http://localhost:8080/users -X PUT
UpdateUser :
✗ curl http://localhost:8080/users -X DELETE
DeleteUser :
/users 에대서 3개의 메소드 호출이 정상적으로 라우팅 됨을 확인할 수 있다.
✗ curl http://localhost:8080/my -X PUT
Call My Page :
✗ curl http://localhost:8080/my -X POST
Call My Page :
✗ curl -i http://localhost:8080/my -X GET
HTTP/1.1 405 Method Not Allowed
Date: Thu, 10 Dec 2020 06:57:42 GMT
Content-Length: 0
/my 에 대해서는 PUT, POST 만 허용하고, GET 으로 호출했을때 헤더로 HTTP/1.1 405 Method Not Allowed 로 응답되었음을 확인할 수 있다.
이처럼 http method 별로 라우팅을 수행하여 적절한 엔드포인트를 제공할 수 있음을 알게 되었다.
Subrouting 으로 엔드포인트 구분하기.
보통 rest api 는 엔드포인트 prefix 를 구분하여 서비스를 제공한다.
예를 들어 /api 라는 prefix 를 붙여서 api 임을 알려주고, 특정 요구사항에 따라서 엔드포인트를 다양하게 분리할 수 있다.
예시:
- /api/users POST, PUT
- /api/users/{id} GET, DELETE
- /api/users/{id}/summary GET
- /api/subjects POST, PUT
- /api/subjects/{id} GET, DELETE
위와 같다고 하면 다음과 같이 서브 경로를 지정해 줄 수 있다.
main.go 파일을 아래와 같이 수정해보자.
package main
import (
"fmt"
"html"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HelloWorld).Methods("GET")
r.HandleFunc("/path/value", ResponsePath).Methods("GET")
// r.HandleFunc("/users", CreateUser).Methods("POST")
// r.HandleFunc("/users", UpdateUser).Methods("PUT")
// r.HandleFunc("/users", DeleteUser).Methods("DELETE")
// r.HandleFunc("/my", CallMy).Methods("POST", "PUT")
mainSubRouter := r.PathPrefix("/api").Subrouter()
userSubRouter := mainSubRouter.PathPrefix("/users").Subrouter()
userSubRouter.HandleFunc("", CreateUser).Methods("POST")
userSubRouter.HandleFunc("/", UpdateUser).Methods("PUT")
userSubRouter.PathPrefix("/{id}").HandlerFunc(SelectUser).Methods("GET")
userSubRouter.PathPrefix("/{id}").HandlerFunc(DeleteUser).Methods("DELETE")
subjectSubRouter := mainSubRouter.PathPrefix("/subjects").Subrouter()
subjectSubRouter.PathPrefix("/").HandlerFunc(CreateSubject).Methods("POST")
subjectSubRouter.PathPrefix("/").HandlerFunc(UpdateSubject).Methods("PUT")
subjectSubRouter.PathPrefix("/{id}").HandlerFunc(SelectSubject).Methods("GET")
subjectSubRouter.PathPrefix("/{id}").HandlerFunc(DeleteSubject).Methods("DELETE")
fmt.Println("Server start on port: ", 8080)
log.Fatal(http.ListenAndServe(":8080", r))
}
func HelloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
}
func ResponsePath(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Your request path is :%q", html.EscapeString(r.URL.Path))
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "CreateUser :")
}
func SelectUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "SelectUser :")
}
func UpdateUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "UpdateUser :")
}
func DeleteUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "DeleteUser :")
}
func CallMy(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Call My Page :")
}
func CreateSubject(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "CreateSubject :")
}
func UpdateSubject(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "UpdateSubject :")
}
func SelectSubject(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "SelectSubject :")
}
func DeleteSubject(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "DeleteSubject :")
}
변경이 발생된 부분은 아래와 같다.
... 생략
mainSubRouter := r.PathPrefix("/api").Subrouter()
userSubRouter := mainSubRouter.PathPrefix("/users").Subrouter()
userSubRouter.HandleFunc("", CreateUser).Methods("POST")
userSubRouter.HandleFunc("/", UpdateUser).Methods("PUT")
... 생략
- r.PathPrefix(“/api”).Subrouter(): Subrouter 를 생성하고, prefix 하위에 필요한 라우팅을 묶어줄 수 있다.
- userSubRouter.HandleFunc(“”, CreateUser).Methods(“POST”): 부분은 prefix 를 ““로 두었고 핸들 함수를 정의하고 있다.
- userSubRouter.HandleFunc(“/”, UpdateUser).Methods(“PUT”): 부분은 위 내역과 동일하며, prefix 를 “/”로 두었다.
테스트 수행하기
✗ curl http://localhost:8080/api/users/1
SelectUser :
✗ curl http://localhost:8080/api/users/ -X POST
CreateUser :
✗ curl http://localhost:8080/api/users/ -X PUT
404 page not found
✗ curl http://localhost:8080/api/subjects/1
SelectSubject :
✗ curl http://localhost:8080/api/subjects/ -X POST
CreateSubject :
보는 바와 같이 curl http://localhost:8080/api/users/ -X PUT 로 처리되면 404 page not found 가 되었음을 알 수 있다.
Wrap Up
지금까지 라우팅에 대한 기본적인 사항에 대해서 알아 보았다.
추가적인 필터링과 호스트 필터링 등에 대한 내역은 Document 문서를 참고하면 좋을듯 하다.
관련 Git 에서 소스코드를 확인 가능
'Go' 카테고리의 다른 글
[Go] Go Web Programming Basic 05 - 파라미터 처리 (0) | 2022.04.14 |
---|---|
[Go] Go Web Programming Basic 04 - Routing 모듈로 분리하기 (0) | 2022.04.14 |
[Go] Go Web Programming Basic 02 - Install Gorilla (0) | 2022.04.14 |
[Go] Go Web Programming Basic 01 (0) | 2022.04.14 |
AWS Go WebProgram 과 RDS 연동 하기 (무대뽀 버젼) (0) | 2022.04.14 |
- Total
- Today
- Yesterday
- NodeSelector
- Terraform
- kubernetes
- springboot
- tfsec
- mongo
- Database
- D3
- argocd
- AWS
- kafka-springboot
- Golang
- Spring
- Kafka
- docker
- go
- declative
- java
- kubectl
- MySQL
- CI
- Gorilla
- docker-compose
- MongoDB
- deploy
- mapping
- gitops
- CD
- jenkins
- jpa
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |