Golang. Настройка сервера к api запросам
подскажите, можно ли создать функцию которая будет автоматически проставлять стандартные заголовки, к примеру если у меня идёт обработка по адресу /api
http.HandleFunc("/api/count_users", countUsersHandler)
http.HandleFunc("/api/count_payments", countPaymentsHandler)
http.HandleFunc("/api/average_payments", averagePaymentHandler)
То во всех случаях нужно в каждой функции прописывать заголовки:
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.Header().Set("Content-Type", "application/json")
А также во всех случаях нужно конвертировать в json:
json.NewEncoder(w).Encode(response)
Можно ли создать функцию к примеру API и просто при каждом запросе на api автоматически это всё проставлять? Вот так:
func countPaymentsHandler(w http.ResponseWriter, r *http.Request) {
var count int
err := db.QueryRow("SELECT COUNT(*) FROM payments WHERE `status` = '1'").Scan(&count)
if err != nil {
http.Error(w, "Ошибка при выполнении запроса", http.StatusInternalServerError)
return
}
response := map[string]int{"count": count}
return response
}
func API(pattern string, handler func()) {
http.HandleFunc("/api/"+pattern, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
response := handler
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
})
}
func main() {
initDB()
defer db.Close()
API("count_payments", countPaymentsHandler)
fmt.Println("Сервер запущен на http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Ответы (1 шт):
Я обычно делаю с помощью middleware - прослойка между http сервером и обработчиком. Вот так примерно это выглядит:
// mw - сокращение middleware
func mw(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.Header().Set("Content-Type", "application/json")
handler(w, r)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`{"a": 123}`))
}
func main() {
http.HandleFunc("/path", mw(handler))
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil {
log.Fatal(err)
}
}
Естественно mw
можно переименовать в какой-нибудь SetApiHeaders
и вынести в пакет middlewares
. Также можно использовать несколько прослоек на 1 обработчик: http.HandleFunc("/path", SetStandartsHeaders(SetApiHeaders(handler)))