지금 내가 해야 하는 일
1. RESTful API 만들기
2. Todo 구조체 만들기
3. API에 맞는 핸들러 만들기
4. HTML 문서 만들기
5. 자바스크립트 코드 만들기
6. 최종 검수
RESTful API를 만들 땐 gorilla/mux만 썼던 것 같은데 오늘은 urfave/negroni와 unrolled/render도 쓴다.
참고
"Gorilla Mux"라는 이름은 "Gorilla Multiplexer"의 줄임말입니다. 여기서 "Multiplexer"는 여러 입력 신호 중 하나를 선택해서 단일 출력 라인에 전달하는 장치를 의미하는 전자공학 용어에서 유래되었는데, 웹 개발의 컨텍스트에서는 다양한 HTTP 요청(URL, 메소드 등)을 적절한 핸들러로 라우팅하는 기능을 지칭합니다.
"고릴라(Gorilla)"는 이 라이브러리가 속한 더 큰 Gorilla 웹 툴킷의 일부분으로, Go 언어로 웹 애플리케이션을 개발할 때 사용되는 다양한 라이브러리와 패키지의 모음입니다. Gorilla 툴킷은 웹소켓, 세션 관리, 라우팅 등 다양한 기능을 제공합니다.
나는 negroni를 미들웨어 라이브러리라고 생각했는데
터커님이 '핸들러'라고도 표현을 하셨다.
그에 대해 gpt가 준 이 답변이 명확한 것 같아 첨부한다.
미들웨어와 핸들러는 각각의 목적과 역할이 있습니다:
미들웨어: 주로 HTTP 요청과 응답을 처리하는 전/후 처리 단계에서 사용됩니다. 로깅, 인증, 입력 검증, CORS 처리, 에러 핸들링 등과 같은 거의 "표준화된" 작업에 사용됩니다. 비즈니스 로직의 복잡성을 줄이기 위해, 이러한 일반적인 작업을 미들웨어에 위임하는 것이 좋습니다.
핸들러: 특정 요청에 대한 구체적인 비즈니스 로직을 실행하는 곳입니다. 예를 들어, 데이터베이스에서 데이터를 조회하거나, 데이터를 처리하고 결과를 반환하는 등의 작업이 여기에 해당합니다.
미들웨어가 비즈니스 로직을 전혀 처리하지 않는 것은 아닙니다. 예외적인 상황에서, 특정 미들웨어가 비즈니스 로직의 일부를 수행할 수도 있습니다. 하지만 일반적으로, 비즈니스 로직은 핸들러에서 처리하는 것이 좋습니다. 이렇게 구분하는 이유는 관심사의 분리(separation of concerns) 원칙을 따르기 위해서입니다. 코드의 가독성, 유지보수성, 확장성을 높이기 위해 비즈니스 로직은 명확하게 핸들러에 집중되어야 하며, 미들웨어는 요청/응답의 사전 처리나 사후 처리에 집중하는 것이 좋습니다.
여러 가지 이유가 있을 수 있지만 여기서는 웹 서버 응답을 구현하기 좋아 사용한다.
GET, POST, PUT, DELETE를 만들 건데요(CRUD),
URL은
/todos, /todos, /todos/id, /todos/id
이렇게 잡습니다.
설계(?)가 끝났으면 웹 서버를 만듭니다.
... 책 내용 진행 중 ...
func RemoveTodoHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) // ➐ ID에 해당하는 할 일 삭제
id, := strconv.Atoi(vars["id"])
if , ok := todoMap[id]; ok {
delete(todoMap, id)
rd.JSON(w, http.StatusOK, Success{true})
} else {
rd.JSON(w, http.StatusNotFound, Success{false})
}
}
이 부분이 너무 이해가 안 돼서...
func RemoveTodoHandler(w http.ResponseWriter, r *http.Request) {
이 줄은 RemoveTodoHandler라는 함수를 정의합니다. 이 함수는 HTTP 요청을 처리하는 핸들러로, http.ResponseWriter와 http.Request를 매개변수로 받습니다.
vars := mux.Vars(r)
mux.Vars(r)는 현재 HTTP 요청에 포함된 경로 변수를 가져옵니다. 여기서 r은 현재의 HTTP 요청을 나타내고, vars는 경로 변수를 저장하는 맵(map)입니다.
id, _ := strconv.Atoi(vars["id"])
strconv.Atoi 함수는 문자열을 정수로 변환합니다. 여기서 vars["id"]로 요청 경로에서 "id" 변수를 가져오고, 이를 정수로 변환하여 id 변수에 저장합니다. _는 Go에서 값을 무시하겠다는 의미의 블랭크 식별자입니다.
if _, ok := todoMap[id]; ok {
todoMap은 id를 키로 하고 Todo 구조체를 값으로 하는 맵입니다. 이 줄은 id에 해당하는 항목이 todoMap에 존재하는지를 검사합니다. ok는 todoMap에 해당 id가 존재하는지의 여부를 나타내는 불리언 값입니다.
delete(todoMap, id)
delete 함수는 맵에서 키에 해당하는 요소를 제거합니다. 여기서 todoMap 맵에서 id 키를 가진 요소를 제거합니다.
rd.JSON(w, http.StatusOK, Success{true})
rd.JSON 함수는 Success{true} 구조체를 JSON 형식으로 인코딩하여 HTTP 응답으로 보냅니다. http.StatusOK는 HTTP 상태 코드 200을 나타내며, 이는 요청이 성공적으로 처리되었음을 의미합니다.
} else {
만약 todoMap에서 해당 id를 찾지 못한다면, else 블록이 실행됩니다.
rd.JSON(w, http.StatusNotFound, Success{false})
이 줄은 todoMap에서 해당 id가 없을 경우, 즉 할 일 항목이 존재하지 않을 때 실행됩니다. http.StatusNotFound는 HTTP 상태 코드 404를 나타내며, 클라이언트에게 요청한 자원을 찾을 수 없음을 알립니다. Success{false}는 작업이 성공하지 않았음을 클라이언트에게 알리는 JSON 응답입니다.
}
이 괄호는 if 문의 끝을 나타냅니다.
이 함수의 전체적인 작업 흐름은 클라이언트가 보낸 요청에 포함된 id를 사용하여 todoMap에서 해당하는 할 일 항목을 찾아 삭제하는 것입니다. 삭제에 성공하면 성공 메시지를, 실패하면 실패 메시지를 JSON 형식으로 클라이언트에 전송합니다.
... 책 그대로 따라 하면 문제 없이 헤로쿠로 배포 전 단계까지 감 ...
헤로쿠 배포 시 발생할 수 있는 문제...
나는 내가 배포까지 했다고 자체 최면을 건 뒤
이 챕터를 마무리한다.
Tucker의 Go 언어 프로그래밍 - Todo 리스트 웹 사이트 만들기편 끝!