Як я можу обробляти http-запити різних методів до / в Go?


79

Я намагаюся зрозуміти, як найкраще обробляти запити /і лише /в Go, і по-різному обробляти різні методи. Ось найкраще, що я придумав:

package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/" {
            http.NotFound(w, r)
            return
        }

        if r.Method == "GET" {
            fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path))
        } else if r.Method == "POST" {
            fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path))
        } else {
            http.Error(w, "Invalid request method.", 405)
        }
    })

    log.Fatal(http.ListenAndServe(":8080", nil))
}

Це ідіоматичний Go? Це найкраще, що я можу зробити зі стандартною http-бібліотекою? Краще я б зробив щось на зразок http.HandleGet("/", handler)експресу чи Синатри. Чи існує хороша основа для написання простих послуг REST? web.go виглядає привабливо, але здається застійним.

Дякую за вашу пораду.


2
Вас може зацікавити gorillatoolkit.org/pkg/mux, якщо Ви шукаєте лише абстракцію маршрутизації.
dskinner

1
+1. mux або gorillatoolkit.org/pkg/pat чудово підходять для абстрагування цього.
minikomi

Відповіді:


98

Щоб ви служили лише корінню: Ви робите правильно. У деяких випадках вам потрібно буде викликати метод ServeHttp об'єкта http.FileServer замість виклику NotFound; це залежить від того, чи є у вас різні файли, які ви також хочете обслуговувати.

Щоб по-різному обробляти різні методи: Багато моїх обробників HTTP не містять нічого, крім оператора перемикання, подібного до цього:

switch r.Method {
case http.MethodGet:
    // Serve the resource.
case http.MethodPost:
    // Create a new record.
case http.MethodPut:
    // Update an existing record.
case http.MethodDelete:
    // Remove the record.
default:
    // Give an error message.
}

Звичайно, ви можете виявити, що такий сторонній пакет, як горила, працює для вас краще.


32

е, я насправді прямував до ліжка, і, отже, швидкий коментар щодо перегляду http://www.gorillatoolkit.org/pkg/mux, який справді приємний і робить те, що ти хочеш, просто переглянь документацію. Наприклад

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/products", ProductsHandler)
    r.HandleFunc("/articles", ArticlesHandler)
    http.Handle("/", r)
}

і

r.HandleFunc("/products", ProductsHandler).
    Host("www.domain.com").
    Methods("GET").
    Schemes("http")

та багато інших можливостей та способів виконання вищезазначених операцій.

Але я відчув потребу розглянути іншу частину запитання: "Це найкраще, що я можу зробити". Якщо std lib трохи голий, чудовий ресурс для перевірки тут: https://github.com/golang/go/wiki/Projects#web-libraries (спеціально пов’язаний з веб-бібліотеками).


І не забудьте зареєструвати свій новий маршрутизатор rяк обробник у вашому Serverекземплярі
MAZux
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.