Почему не показывается json файл по указанному роуту?
Написал такой код
import (
"net/http"
"github.com/gin-gonic/contrib/static"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.Use(static.Serve("/", static.LocalFile("./client/build", true)))
router.Use(static.Serve("/export", static.LocalFile("./server/db.json", true)))
api := router.Group("/api")
{
api.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong api/"})
})
api.GET("/export", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong api/export"})
})
}
router.Run(":5000")
}
В папке server лежит тестовый файл db.json
{
"items": [
{ "id": 1, "name": "Яблоки", "price": "$2" },
{ "id": 2, "name": "Персики", "price": "$5" }
]
}
Этот JSON-объект взял отсюда https://ru.reactjs.org/docs/faq-ajax.html и принимаю как в статье и написано
componentDidMount() {
fetch("./api")
.then(response => {
console.log("router: /api");
console.log("response: ", response);
return response.json();
})
.then(json => console.log("json: ", json));
fetch("./api/export")
.then(response => {
console.log("router: /api/export");
console.log("response: ", response);
return response.json();
})
.then(json => console.log("json: ", json))
}
Но по адресу localhost:5000/api/export показывает такой json
{"message": "pong api/export"}
Почему так происходит?
Думал, что строка
router.Use(static.Serve("/", static.LocalFile("./client/build", true)))
развернет приложение на localhost:5000/,
а строка
router.Use(static.Serve("/export", static.LocalFile("./server/db.json", true)))
развернет файл db.json по адресу localhost:5000/export.
Ну и группировка обоих роутов в корень /api
router.Group("/api")
Тогда же приложение должно быть на адресе localhost:5000/api/,
а db.json — на адресе localhost:5000/api/export ?
P.S. добавляю изменение, неправильно понял группировку роутов, тем не менее проблема не решена, файл JSON не отображается по роуту.
func main() {
router := gin.Default()
router.Use(static.Serve("/", static.LocalFile("./client/build", true)))
router.GET("/export", static.Serve("/", static.LocalFile("./server/db.json", true)))
router.GET("/root", handleDataPerJson)
router.Run(":5000")
}
func handleDataPerJson(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Carabas-Barabas connected!"})
}
На роуте localhost:5000/export файла db.json нет.
Ответы (2 шт):
группировка работает не так, как вы ожидаете. Группировка как раз нужна для того, чтобы объединять несколько эндпоинтов в одну. вместо того, чтобы писать
api.GET("/api/", ....
api.GET("api/export",
вы завернули в группу и опустили префикс api. Также группировка помогает управлять валидацей, верификацией и т.п. конкретно нужных эндпоинтов.
в вашем случае роуты будут такие
GET / "client/build"
GET /export "server/db.json"
GET /api "message": "pong api/"
GET /api/export "message": "pong api/export"
Примечание: не получится по одному роуту указывать 2 разных хэндлера. поэтому, все 4 роута должны быть разные
Всё дело в функции
static.Serve("/", static.LocalFile("./client/build", true))
Первый её аргумент совсем не должен повторять имя папки/файла из структуры проекта, а второй аргумент должен указывать на папку с файлами (либо файл) внутри проекта. В данном случае папка ./client/build будет располагаться по роуту http://localhost:5000/, где последний слеш / и является первым аргументом рассматриваемой функции.
В моём случае файл внутри проекта расположен по пути ./server/db.json. Если написать функцию так
static.Serve("/database", static.LocalFile("./server", true))
то по роуту http://localhost:5000/database будет имя файла db.json, при клике на который произойдёт проваливание на роут http://localhost:5000/db.json, т.о. произошел выход из database, а значит и из папки ./server, но вне её файла db.json нет, следовательно, 404 not found.
Поэтому правильно будет так
static.Serve("/database/", static.LocalFile("./server", true))