GO千练——简单web

68 阅读3分钟

简单Web

参考官方示例:Writing Web Applications

先看效果,再上代码 image.png image.png image.png

wiki.go

package main

import (
	"html/template"
	"io/ioutil"
	"net/http"
	"regexp"
)

// Page 定义 wiki 结构体
type Page struct {
	Title string // 主题
	Body  []byte // 内容
}

// save 保存 wiki 内容到文件
func (p *Page) save() error {
	filename := p.Title + ".txt"
	return ioutil.WriteFile(filename, p.Body, 0600)
}

// loadPage 加载 wiki 内容
func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}

// viewHandler 渲染 view.html
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

// editHandler 渲染 edit.html
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

// saveHandler 保存 wiki
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

// 创建 html 渲染模板
var templates = template.Must(template.ParseFiles("edit.html", "view.html"))

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// 路径校验正则表达式
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")

// makeHandler 创建 Handler 公共方法
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

func main() {
	// 注册 url 请求 Handler
	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))

	// 启动 web 服务端
	http.ListenAndServe(":8080", nil)
}

edit.html

<h1>{{.Title}}</h1>

<form action="/save/{{.Title}}">
  <textarea name="body">
    {{printf "%s" .Body}}
  </textarea>
  <br>
  <input type="submit" value="save">
</form>

view.html

<h1>{{.Title}}</h1>

<p>[<a href="/edit/{{.Title}}">edit</a>]</p>

<div>{{printf "%s" .Body}}</div>

根据上面的代码,即可了解Go语言是如何实现 web 开发的。 然后引出目前常见的 Go Web 框架,下面简单介绍 Gin、Echo、Beego 框架。

Go Web 开源框架

白开水一般的 Gin

Gin 是一个使用 Go 语言开发的 Web 框架。 它提供类似 Martini 的API ,但性能更佳,速度提升高达 40 倍。 如果你是性能和高效的追求者, 你会爱上 Gin。

Martini 是 Go 生态中的一个 Web 框架,诞生于 2013 年比较早,Gin 是诞生于 2015 年的“后辈”

特点

  • 快速:基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
  • 支持中间件:传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。
  • Crash 处理:Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。保证服务始终可用。
  • JSON 验证:Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
  • 路由组: Gin 帮助更好地组织路由,例如,按照需要授权和不需要授权和不同API版本进行分组。此外,路由分组可以无限嵌套而不降低性能。
  • 错误管理:Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
  • 内置渲染:Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
  • 可扩展性:新建一个中间件非常简单。

更多信息请参考官网:gin-gonic.com/zh-cn/ github:github.com/gin-gonic/g…

极简 Echo

高性能、可扩展、极简的 Go Web 框架

特点

  • 拥有可以智能地确定优先级的 HTTP 路由器
  • 轻松构建健壮且可扩展的 RESTful API
  • 支持组 Group APIs
  • 支持可扩展的中间件框架

更多信息请参考官网:echo.laily.net/ github: github.com/labstack/ec…

简约&强大 Beego

Beego 用于在 Go 中快速开发企业应用程序,包括 RESTful API、Web 应用程序和后端服务。 image.png

主要由四部分组成:

  • Base 基础模块:包括 log 模块、config 模块、governor 模块
  • Task 任务:用于运行定时任务或周期性任务;
  • Client 客户端:包括 ORM 模块、httplib 模块、缓存模块;
  • Server 服务器:包括网页模块。

更多信息请参考 github: github.com/beego/beego

请关注公众号【Java千练】,更多干货文章等你来看!

qrcode_for_gh_e39063348296_258.jpg