REST API_GoLang Practice Develop

wldbs._.·2024년 9월 4일
0

REST API & Go

목록 보기
1/5
post-thumbnail

이전에 진행한 RESTful API 실습 업그레이드

사용자가 이전에 조회한 id 다음 학생을 조회하자

사용자가 특정 id를 지정해 학생을 조회한다
-> 해당 id를 lastQueriedId에 저장
-> /next 에 접속하면 nextId는 lastQueriedId에 1을 더한 값, 그리고 nextId는 lastQueriedId로 된다


1. 패키지 Import 및 데이터 구조체 정의

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
}

2. 전역변수 선언

var students map[int]Student

var lastId int

var lastQueriedId int // 사용자가 마지막으로 조회한 ID

3. 라우터/웹 핸들러 함수 등록 및 데이터 삽입

func MakeWebHandler() http.Handler {
	mux := mux.NewRouter()

	// 1. 학생 전체 목록 조회
	mux.HandleFunc("/students", GetStudentListHandler).Methods("GET")

	//2. 특정 학생 정보 조회
	mux.HandleFunc("/students/{id:[0-9]+}", GetStudentHandler).Methods("GET")

	// 3. 학생 데이터 추가
	mux.HandleFunc("/students", PostStudentHandler).Methods("POST")

	// 4. 학생 데이터 삭제
	mux.HandleFunc("/students/{id:[0-9]+}", DeleteStudentHandler).Methods("DELETE")

	// 5. 이전 조회한 id 다음 학생 조회 [0904]
	mux.HandleFunc("/students/next", GetNextStudentHandler).Methods("GET")

	// 초기 학생 데이터 설정
	students = make(map[int]Student)

	students[1] = Student{1, "aaa", 16, 87}
	students[2] = Student{2, "bbb", 18, 98}
	students[3] = Student{3, "ccc", 20, 85}
	students[4] = Student{4, "ccc", 11, 70}
	students[5] = Student{5, "ddd", 22, 76}
	students[6] = Student{6, "eee", 33, 82}
	students[7] = Student{7, "fff", 44, 83}
	students[8] = Student{8, "ggg", 55, 96}
	students[9] = Student{9, "hhh", 66, 62}
	students[10] = Student{10, "iii", 77, 34}

	lastId = 10

	return mux
}

4. Sort 인터페이스 구현


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
}

5. 핸들러 함수 정의

// 1. 저장된 모든 학생 정보를 JSON 형식으로 반환하는 핸들러
func GetStudentListHandler(w http.ResponseWriter, r *http.Request) {
	list := make(Students, 0)
	for _, student := range students {
		list = append(list, student)
		sort.Sort(list) // ID를 기준으로 학생 목록을 정렬
		w.WriteHeader(http.StatusOK)
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(list)
}
// 2. 요청된 ID에 해당하는 학생 정보를 JSON 형식으로 반환
func GetStudentHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)                 // 인수(id) 추출
	id, err := strconv.Atoi(vars["id"]) // URL에서 id를 정수로 변환
	if err != nil {
		http.Error(w, "Invalid student ID", http.StatusBadRequest)
		return
	}

	student, ok := students[id]
	if !ok {
		http.Error(w, "Student not found", http.StatusNotFound)
		return
	}

	lastQueriedId = id // 마지막으로 조회된 학생의 ID 업데이트!

	w.WriteHeader(http.StatusOK)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(student)
}
// 3. 새로운 학생 데이터를 받아서 시스템에 추가 & 추가한 학생 정보 볼 수 있도록 수정 (09/02)
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) // 디코딩 실패 시, HTTP 400 상태 코드 반환
		return
	}
	lastId++
	student.Id = lastId
	students[lastId] = student

	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(student)
}
// 4. 주어진 ID에 해당하는 학생 데이터를 제거 & 성공적으로 제거 여부 표시 (09/02)
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) // HTTP 404 (Not Found) 반환
		return
	}

	// 존재하는 경우, 맵에서 해당 학생 정보 삭제
	delete(students, id)
	w.WriteHeader(http.StatusOK) // 성공적으로 학생 데이터를 삭제한 경우, HTTP 200 (OK)
}
// 5. next 학생 조회 핸들러 (09/04)
func GetNextStudentHandler(w http.ResponseWriter, r *http.Request) {
	if lastQueriedId == 0 {
		http.Error(w, "No student has been queried yet", http.StatusNotFound)
		return
	}

	nextId := lastQueriedId + 1 // 최근에 조회된 다음 id 설정
	student, ok := students[nextId]

	if !ok {
		w.WriteHeader(http.StatusNotFound) // 학생 데이터를 찾지 못한 경우 404 에러 반환
		return
	}

	lastQueriedId = nextId // 다음 학생의 ID로 업데이트

	w.WriteHeader(http.StatusOK)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(student)
}

6. 데이터 출력 함수 구현

// students 맵에 저장된 모든 학생의 정보를 출력 -> 테스트 코드에 출력하려고! (09/02)
func PrintStudents() {
	fmt.Println("Current students in map:")
	for id, student := range students {
		fmt.Printf("ID: %d, Name: %s, Age: %d, Score: %d\n", id, student.Name, student.Age, student.Score)
	}
	fmt.Println("")
}

7. 메인 함수 - 서버 구동

func main() {
	http.ListenAndServe(":3000", MakeWebHandler()) // 3000번 포트에서 HTTP 서버 시작
	// MakeWebHandler에서 반환된 핸들러를 사용하여 요청 처리
	// http://localhost:3000/students로 요청을 보내면, 서버는 두 개의 미리 정의된 학생 데이터를 JSON 형식으로 응답
	// -> 이 데이터는 Id 기준으로 정렬된 상태로 반환
}
profile
공부 기록용 24.08.05~ #LLM #RAG

0개의 댓글