обзор
В предыдущем разделе мы использовали фреймворк Gin для быстрого создания интерфейса GET-запроса, сегодня мы узнаем, как получить маршруты и параметры.
глагол запроса
Знаком сRESTful
студенты должны знать, чтоRESTful
Это стиль дизайна и метод разработки сетевых приложений.Каждый URI представляет собой ресурс.POST
,DELETE
,PUT
,GET
Существует четыре метода запросов для добавления, удаления, изменения и запроса ресурсов.
Точно так же, в дополнение к этим четырем глаголам, структура Gin предоставляет намPATCH
,OPTION
,HEAD
Подождите, подробности можно посмотретьrentergroup.go
документIRoutes
интерфейс.
type IRoutes interface {
Use(...HandlerFunc) IRoutes
Handle(string, string, ...HandlerFunc) IRoutes
Any(string, ...HandlerFunc) IRoutes
GET(string, ...HandlerFunc) IRoutes
POST(string, ...HandlerFunc) IRoutes
DELETE(string, ...HandlerFunc) IRoutes
PATCH(string, ...HandlerFunc) IRoutes
PUT(string, ...HandlerFunc) IRoutes
OPTIONS(string, ...HandlerFunc) IRoutes
HEAD(string, ...HandlerFunc) IRoutes
StaticFile(string, string) IRoutes
Static(string, string) IRoutes
StaticFS(string, http.FileSystem) IRoutes
}
так какRenterGroup
ДостигнутоIRoutes
определены все глаголы запроса, иgin.Default
возвращениеEngine
Тип наследуетRenterGroup
, поэтому его очень просто использовать, просто передайтеgin.Default
Создайте экземпляр объекта, и все последующие операции маршрутизации можно будет использовать через этот объект.
func main() {
router := gin.Default()
router.POST("/article", func(c *gin.Context) {
c.String(200, "article post")
})
router.DELETE("/article", func(c *gin.Context) {
c.String(200, "article delete")
})
router.PUT("/article", func(c *gin.Context) {
c.String(200, "article put")
})
router.GET("/article", func(c *gin.Context) {
c.String(200, "article get")
})
router.Run()
}
Первый параметр команды запроса — это путь запроса, а второй параметр — это функция, используемая для логической обработки, которая может быть анонимной или иметь имя функции, определенное в другом месте. Различные глаголы запроса могут определять один и тот же путь, и нужно только переключить глаголы, чтобы войти в соответствующую логику обработки.
curl -X PUT http://localhost:8080/article
curl -X POST http://localhost:8080/article
curl -X GET http://localhost:8080/article
curl -X DELETE http://localhost:8080/article
параметр маршрута
Существует два типа запросов GET, один из которых добавляется после URL-адреса.?name=pingye
, у этого есть имя параметра, а другой должен добавить значение параметра непосредственно к пути/article/1
, который не имеет имени параметра и должен быть проанализирован в коде.
protocol://hostname:[port]/path/[query]#fragment
Давайте сначала посмотрим на геймплей маршрутизации, несущей значения параметров, Вот вопрос, как использовать Gin для получения значений параметров по следующей ссылке1
.
Реализация очень проста, просто нужно установить заполнитель в маршруте:id
, двоеточие является знаком заполнителя, имя параметра после двоеточия можно настроить, Джин сопоставит маршрут с адресом запроса, если совпадение прошло успешно, будет1
назначить в качестве заполнителя:id
, просто позвониc.Param
вы можете получитьid
значение .
router.GET("/article/:id", func(c *gin.Context) {
id := c.Param("id")
c.String(200, id)
})
но,:id
Существует проблема с заполнителями, еслиid
Если значение параметра передано пустым, будет404
сообщение об ошибке.
Итак, Джин предоставляет еще один заполнитель*id
, вы можете использовать его для достижения цели получения нулевого значения.
router.GET("/article/*id", func(c *gin.Context) {
id := c.Param("id")
c.String(200, id)
})
Общие параметры
Помимо значений параметров, переносимых маршрутом, рассмотрим более традиционныеGET
способ передачи параметров.
http://localhost:8080/welcome?firstname=Jane&lastname=Doe
в состоянии пройтиc.Query
илиc.DefaultQuery
Метод получает параметр после вопросительного знака.
router.GET("/welcome", func(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "pingyeaa")
lastname := c.Query("lastname")
c.String(200, firstname+" "+lastname)
})
Оба они в конечном итоге вызываютGetQuery
метод, разница только вDefaultQuery
Выполните обработку значений по умолчанию.
func (c *Context) DefaultQuery(key, defaultValue string) string {
if value, ok := c.GetQuery(key); ok {
return value
}
return defaultValue
}
func (c *Context) Query(key string) string {
value, _ := c.GetQuery(key)
return value
}
параметр формы
Форма отправлена из HTMLform
Контент также легко доступен.
router.POST("/form_post", func(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous")
c.JSON(200, gin.H{
"status": "posted",
"message": message,
"nick": nick,
})
})
curl -d "message=pingye" http://localhost:8080/form_post
{"message":"pingye","nick":"anonymous","status":"posted"}
параметр типа массива
Иногда (например, флажки) интерфейсная страница будет передавать значение типа массива, этот типname
То же самое, но хранимый контент другой.
POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
Content-Type: application/x-www-form-urlencoded
все ещеQueryMap
Метод выполнен, метод возвращается по умолчаниюmap
тип.
router.GET("/post", func(c *gin.Context) {
ids := c.QueryMap("ids")
c.String(200, ids["a"]+" "+ids["b"])
})
curl http://localhost:8080/post?ids[a]=pingye&ids[b]=hehe
pingye hehe
Файл загружен
При нормальных обстоятельствах загрузка файла будет напрямую передаваться из внешнего интерфейса поставщикам услуг облачного хранения, таким как Alibaba Cloud, Qiniu Cloud и т. д., и относительно небольшое количество сценариев будет передаваться на их собственные серверы. чтобы избежать书到用时方恨少
бывает, давайте разбираться.
Джин обеспечиваетFormFile
метод для получения файлового потока, этот метод возвращаетFileHeader
Переменная типа, которую можно вызватьFilename
свойства, чтобы увидеть имя файла.
type FileHeader struct {
Filename string
Header textproto.MIMEHeader
Size int64
content []byte
tmpfile string
}
router.POST("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.String(200, file.Filename)
})
пройти черезcurl
Запросив интерфейс, вы можете видеть, что легко получить имя файла.
curl -X POST http://localhost:8080/upload \
-F "file=@/Users/enoch/Downloads/IMG_9216.JPG" \
-H "Content-Type: multipart/form-data"
IMG_9216.JPG
Конечно, мы можем не только получить имя файла, но и использоватьSaveUploadedFile
Метод сохраняет файл в определенное место.При сохранении файла убедитесь, что у вас есть разрешение на операцию целевого каталога.
router.POST("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.String(200, file.Filename)
err := c.SaveUploadedFile(file, "/Users/enoch/Desktop/ab.png")
if err != nil {
c.String(500, err.Error())
}
})
пакеты маршрутизации
При значительных изменениях в интерфейсе (таких как параметры ввода и вывода) с учетом обратной совместимости обычно добавляется интерфейс, но есть надежда, что имя нового интерфейса, очевидно, является обновленной версией старого интерфейса. Префикс имени с номером версииv1/article
эта форма.
v1 := r.Group("v1")
{
v1.POST("/login", func(c *gin.Context) {
c.String(200, "v1/login")
})
v1.POST("/submit", func(c *gin.Context) {
c.String(200, "v1/submit")
})
}
v2 := r.Group("v2")
{
v2.POST("/login", func(c *gin.Context) {
c.String(200, "v2/login")
})
v2.POST("/submit", func(c *gin.Context) {
c.String(200, "v2/submit")
})
}
curl -X POST http://localhost:8080/v1/login
curl -X POST http://localhost:8080/v2/login
Пример кода языковой библиотеки Go, приветственная звездочкаGitHub.com/Hiranoahah/go…
Спасибо за просмотр.Если вы считаете, что статья была вам полезна, обратите внимание на паблик-аккаунт "Pingye", посвященный языку Go и техническим принципам.