网站图片切换怎么做,wordpress压缩数据库,企业网站源码带手机版,免费软件看视频文章目录 什么是 RESTful APIGo 流行 Web 框架-GinGo HelloWorldGin 路由和控制器Gin 处理请求参数生成 HTTP 请求响应Gin 的学习内容实战用 Gin 框架开发 RESTful APIOAuth 2.0接口了解用 Go 开发 OAuth2.0 接口示例 编程有一个准则——Don‘t Repeat Yourself#xff08;不要… 文章目录 什么是 RESTful APIGo 流行 Web 框架-GinGo HelloWorldGin 路由和控制器Gin 处理请求参数生成 HTTP 请求响应Gin 的学习内容实战用 Gin 框架开发 RESTful APIOAuth 2.0接口了解用 Go 开发 OAuth2.0 接口示例 编程有一个准则——Don‘t Repeat Yourself不要重复你的代码。这个准则的核心概念是如果有一些出现重复的代码则应该把这些代码提取出来封装成一个方法。 随着时间的积累有了一批方法可以把它们整合成工具类。如果工具类形成了规模则可以把它们整合成类库。类库更系统功能更全。不仅不要自己重复造项目中已有的“轮子”也不要造别人已经造好的“轮子”直接使用已有的“轮子”即可。 什么是 RESTful API
资源概述 资源可以是单例或集合资源也可以包含子集合资源REST API 使用统一资源标识符URI来定位资源 使用名词表示资源 文档集合存储控制器 保持一致性 使用正斜杠 \ 表示层次关系不要在 URI 尾部使用正斜杠使用连字符 - 来提高 URI 的可读性不要使用下划线( _ )在 URI 中使用小写字母不要使用文件拓展名 切勿在 URI 中使用 CRUD 函数的名称使用查询参数过滤 URI 集合
Go 流行 Web 框架-Gin
Go HelloWorld
package mainimport (github.com/gin-gonic/gin
)func main() {// 创建一个默认的路由引擎r : gin.Default()// GET请求方式/hello请求的路径// 当客户端以GET方法请求/hello路径时会执行后面的匿名函数r.GET(/hello, func(c *gin.Context) {// c.JSON返回JSON格式的数据c.JSON(200, gin.H{message: Hello world!,})})// 启动HTTP服务默认在0.0.0.0:8080启动服务r.Run()
}
Gin 路由和控制器
路由规则 HTTP 请求方法 GETPOSTPUTDELETE URL 路径 静态 URL 路径带路径的 URL 参数带星号*模糊匹配参数的 URL 路径 处理器函数 分组路由
Gin 处理请求参数
获取 GET 请求参数获取 POST 请求参数获取 URL 路径参数将请求参数绑定到结构体
生成 HTTP 请求响应
以字符串方式生成 HTTP 请求响应以 JSON 格式生成 HTTP 请求响应以 XML 格式生成 HTTP 请求响应以文件格式生成 HTTP 请求响应设置 HTTP 响应头
Gin 的学习内容
Gin 渲染 HTML 模板Gin 处理静态资源Gin 处理 cookieGin 文件上传Gin 中间件Gin Session
实战用 Gin 框架开发 RESTful API
mysql CREATE TABLE users (- id INT UNSIGNED NOT NULL AUTO_INCREMENT,- phone VARCHAR(255) DEFAULT NULL,- name VARCHAR(255) DEFAULT NULL,- password VARCHAR(255) DEFAULT NULL,- PRIMARY KEY (id)- ) ENGINEInnoDB AUTO_INCREMENT39 DEFAULT CHARSETutf8;package mainimport (crypto/sha256fmtgithub.com/gin-gonic/gingorm.io/driver/mysqlgorm.io/gormnet/http
)type (User struct {ID uint json:id gorm:column:idPhone string json:phone gorm:column:phoneName string json:name gorm:column:namePassword string json:password gorm:column:password}UserRes struct {ID uint json:idPhone string json:phoneName string json:name}
)var db *gorm.DBfunc main() {// Connect to the databasevar err errordsn : root:mm..1213tcp(127.0.0.1:3306)/UserManager?charsetutf8mb4parseTimeTruelocLocaldb, err gorm.Open(mysql.New(mysql.Config{DriverName: mysql,DSN: dsn,}), gorm.Config{})if err ! nil {panic(Failed to connect to database)}// Auto migrate the User struct to create the corresponding table in the databaseerr db.AutoMigrate(User{})if err ! nil {panic(Failed to migrate the database)}router : gin.Default()v2 : router.Group(/api/v2/user){v2.POST(/, createUser)v2.GET(/, fetchAllUser)v2.GET(/:id, fetchUser)v2.PUT(/:id, updateUser)v2.DELETE(/:id, deleteUser)}router.Run(:8080)
}func createUser(c *gin.Context) {phone : c.PostForm(phone)name : c.PostForm(name)user : User{Phone: phone,Name: name,Password: md5Password(phone),}tx : db.Begin()if err : tx.Create(user).Error; err ! nil {tx.Rollback()c.JSON(http.StatusInternalServerError, gin.H{error: err.Error(),})return}tx.Commit()c.JSON(http.StatusCreated, gin.H{status: http.StatusCreated,message: User created successfully!,ID: user.ID,})
}func md5Password(password string) string {hash : sha256.Sum256([]byte(password))return fmt.Sprintf(%x, hash)
}func fetchAllUser(c *gin.Context) {var user []Uservar _userRes []UserResdb.Find(user)if len(user) 0 {c.JSON(http.StatusNotFound,gin.H{status: http.StatusNotFound,message: No user found!,})return}for _, item : range user {_userRes append(_userRes,UserRes{ID: item.ID,Phone: item.Phone,Name: item.Name,})}c.JSON(http.StatusOK,gin.H{status: http.StatusOK,data: _userRes,})
}func fetchUser(c *gin.Context) {var user UserID : c.Param(id)db.First(user, ID)if user.ID 0 {c.JSON(http.StatusNotFound, gin.H{status: http.StatusNotFound, message: No user found!})return}res : UserRes{ID: user.ID,Phone: user.Phone,Name: user.Name,}c.JSON(http.StatusOK, gin.H{status: http.StatusOK, data: res})
}func updateUser(c *gin.Context) {var user UseruserID : c.Param(id)db.First(user, userID)if user.ID 0 {c.JSON(http.StatusNotFound, gin.H{status: http.StatusNotFound, message: No user found!})return}db.Model(user).Update(phone, c.PostForm(phone))db.Model(user).Update(name, c.PostForm(name))c.JSON(http.StatusOK, gin.H{status: http.StatusOK,message: Updated User Successfully!,})
}func deleteUser(c *gin.Context) {var user UseruserID : c.Param(id)db.First(user, userID)if user.ID 0 {c.JSON(http.StatusNotFound, gin.H{status: http.StatusNotFound,message: No user found!,})return}db.Delete(user)c.JSON(http.StatusOK, gin.H{status: http.StatusOK, message: User deleted successfully!})
}
GoLand Tools-Http Client 测试
DELETE http://127.0.0.1:8080/api/v2/user/58
Content-Type: application/x-www-form-urlencodedphone10086namechYiDongOAuth 2.0接口了解
用 Go 开发 OAuth2.0 接口示例
做了解之后用到可能性比较小
GitHub OAuth 应用注册
注册页面https://github.com/settings/applications/new
登录授权页面
!DOCTYPE HTML
html
body
a hrefhttps://github.com/login/oauth/authorize?client_id5bcf804cfeb0ef7120f5redirect_urihttp://localhost:8087/oauth/redirectLogin by GitHub
/a
/body
/html欢迎界面
!DOCTYPE HTML
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, INItial-scale1.0meta http-equivX-UA-Compatible contentieedgetitleHello/title
/head
body
/body
script//获取url参数function getQueryVariable(variable) {var query window.location.search.substring(1);var vars query.split();for (var i 0; i vars.length; i) {var pair vars[i].split();if (pair[0] variable) {return pair[1];}}return (false);}// 获取access_tokenconst token getQueryVariable(access_token);// 调用用户信息接口fetch(https://api.github.com/user, {headers: {Authorization: token token}})// 解析请求的JSON.then(res res.json()).then(res {// 返回用户信息const nameNode document.createTextNode(Hi, ${res.name}, Welcome to login our site by GitHub!)document.body.appendChild(nameNode)})
/script
/htmlGo 语言编写
package mainimport (encoding/jsonfmthtml/templatenet/httpos
)// const clientID your client id
const clientID 5bcf804cfeb0ef7120f5// const clientSecret your client secret
const clientSecret 8d31102da18096d13eb6ec819cd81ca898ed7189func hello(w http.ResponseWriter, r *http.Request) {if r.Method GET {t, _ : template.ParseFiles(hello.html)t.Execute(w, nil)}
}func login(w http.ResponseWriter, r *http.Request) {if r.Method GET {t, _ : template.ParseFiles(login.html)t.Execute(w, nil)}
}func main() {http.HandleFunc(/login, login)http.HandleFunc(/, hello)http.HandleFunc(/hello, hello)httpClient : http.Client{}http.HandleFunc(/oauth/redirect, func(w http.ResponseWriter, r *http.Request) {err : r.ParseForm()if err ! nil {fmt.Fprintf(os.Stdout, could not parse query: %v, err)w.WriteHeader(http.StatusBadRequest)}code : r.FormValue(code)reqURL : fmt.Sprintf(https://github.com/login/oauth/access_token?client_id%sclient_secret%scode%s, clientID, clientSecret, code)req, err : http.NewRequest(http.MethodPost, reqURL, nil)if err ! nil {fmt.Fprintf(os.Stdout, could not create HTTP request: %v, err)w.WriteHeader(http.StatusBadRequest)}req.Header.Set(accept, application/json)res, err : httpClient.Do(req)if err ! nil {fmt.Fprintf(os.Stdout, could not send HTTP request: %v, err)w.WriteHeader(http.StatusInternalServerError)}defer res.Body.Close()var t AccessTokenResponseif err : json.NewDecoder(res.Body).Decode(t); err ! nil {fmt.Fprintf(os.Stdout, could not parse JSON response: %v, err)w.WriteHeader(http.StatusBadRequest)}w.Header().Set(Location, /hello.html?access_tokent.AccessToken)w.WriteHeader(http.StatusFound)})http.ListenAndServe(:8087, nil)
}type AccessTokenResponse struct {AccessToken string json:access_token
}