httprouter, использующий путь маршрута с расширением

#go

# #Вперед

Вопрос:

я использую httprouter для простого сервера api json, работающего на golang.

я хотел бы иметь два маршрута с именованными параметрами, обслуживаемых двумя разными обработчиками

например, мне нужно /v1/1234 и /v1/1234.json

     router.GET("/v1/:id", Content)
    router.GET("/v1/:id.json", ContentJson)
 

но именованные параметры соответствуют только одному сегменту пути
. другими способами я могу решить эту проблему?

Комментарии:

1. router.GET("/v1/:id/json", ContentJson) работает ли это для вас?

2. да, это так, и именно таким способом я сейчас пользуюсь. но это некрасиво, я бы предпочел расширение

Ответ №1:

Как вы сказали, именованные параметры соответствуют всему сегменту пути. Вы могли бы обойти это, проверив наличие суффикса в одном обработчике и перейдя оттуда.

 router.GET("/v1/:id", Content)

func Content(w http.ResponseWriter, r *http.Request) {
    params := httprouter.ParamsFromContext(r.Context())

    if strings.HasSuffix(params.ByName("id"), ".json") {
        ContentJson()
    } else {
        ContentDefault()
    }
}
 

Другим способом обработки различных типов ответов без использования нескольких обработчиков является использование заголовка Accept .

 router.GET("/v1/:id", Content)

func Content(w http.ResponseWriter, r *http.Request) {
    if r.Header.Get("Accept") == "application/json" {
        ContentJson()
    } else {
        ContentDefault()
    }
}
 

Затем вы должны установить заголовок в запросе. Это, вероятно, самое чистое решение, но не такое простое для всех пользователей.

 curl -H "Accept: application/json" 'http://my.api/v1/:id`
 

Комментарии:

1. спасибо, я использую проверку суффикса внутри того же обработчика. проверка заголовка также более чистая, но не моя потребность: json предназначен не для использования машинами, а для браузеров.