Go 语言中的 Http 路由基础
最近在写一些 Go 语言的 Web 应用,因为 Go 语言中的 Web 应用和 Python 中的不太一样,具体的区别应该和语言的动态性是有所联系的,同时,也和语言的内置库支持有所联系,所以这就导致了一个现象,那就是 Go 语言中 Web 框架似乎不那么流行(当然我知道国内在吹 Beego),不像 Python 中,各种流行得框架都有不少的支持者。
因为没有框架,所以,在使用的时候一般用一些 Mux 组件配合使用,但是,经常我会搞混一些概念,所以,为了后续更好得提升代码的质量,我先对 Go 的 HTTP 组件基础进行一个小结,顺便分享一下,希望对现在正在看这篇文章的你也有所帮助。
简单的 Web 服务器
在开始其他内容之前,不妨先看一个别人提供的简单的 Web 服务器,看看别人是怎么做的:

这是一个很简单的例子,其实关键点有两个,第一个就是 Line18 - Line 22,这是一个提供了 ServeHTTP 方法的结构体,然后这个结构体的对象在 Line 12 中被直接作为参数使用:
http.ListenAndServe(":8111", db)
看一下 ListenAndServe 函数的原型可以发现 db 的类型应该是 Handler,我们来看一下 Handler 接口:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Handler 接口非常简单,只有一个方法,这个方法接受两个参数,分别是 ResponseWrite 和 Request;这也就是说只要一个结构体实现了 Handler 接口,就可以作为 HTTP 的处理结构体。
更复杂的 Web 服务器
根据前面的理解,那么我们可以实现一个更复杂一些的应用:

这里我们对请求的 URL 路径进行了一些判断,然后根据不同的路径处理不同的代码逻辑,目前看上去尚可,但是一旦当我们的应用复杂之后,那这个函数可能会非常难看,作为提升代码质量的第一步,我们似乎可以很容易得想到抽离函数,但是,简单的抽离函数还是减少不了我们 switch/case 的丑陋局面。所以,为了解决这个问题,Go 语言内置就提供了 URL 组织组件 ServeMux,通过 ServeMux,我们可以更好得管理 URL 路径和代码的问题,下面就展示一下如何使用的例子:

从这里可以看到,引入了 ServeMux 之后,整个代码的风格就变得清新了很多,整个结构也更清晰了,但是,这却只是最粗浅的一层应用,在此之外,Go 语言还为我们做了更简单的简化,在 Line 4 中我们是创建一个 ServeMux,如果我们不自己创建的话,Go 语言内置帮我们创建了一个 DefaultServeMux,我们尽管直接注册就可以了:

这样简约了很多。但是是不是这种方式就够用了呢,好像也不是,想一下如果我们是一个电商网站,前面这两个还只是一个非常非常简单的 item 和 price 的接口,后续还有一大堆的 API 接口呢,这要是都这么注册,那这列表得多长,我们修改查找起来得多复杂。
更高级的 URL 路由
内置的 Mux 虽然使用简单,但是,因为简单,所以功能就弱了一些,例如我们想要的 URL 组路由,也就是说假设我们希望有:
/items/list
/items/add
/items/delete
这几个 URL 的路由都放到 item.go 中实现,然后例如订单类的放 Order 中实现,如果还用内置的 Mux 的话,那注册和修改起来都比较麻烦。
另外,内置的 Mux 无法进行 URL 正则匹配,也无法简单实现 URL Parameter,所以有很多网友就自发得写了一些 Mux 组件,我下面就简单演示一下:github.com/gorilla/mux 这个组件:

这里演示的是一个 URL Parameter 的示例,这是冰山一角,至于更多的功能,如果感兴趣的话可以进上面的链接进行查看。
小结
本文就简单的以一个简单的 Web 服务器例子讲起,描述一下 Go 语言中 HTTP 的路由的一些演变,内容还是比较简单粗糙的,但是,我的目的也仅仅是对这些基础有所了解,从而可以在后续看到高级实现的时候知道实现的原理是啥,做到以不变应万变。
Go 语言中的 Http 路由基础的更多相关文章
- 在Go语言中基础的Redis操作
在Go语言中基础的Redis操作 需要先安装redigo go get "github.com/garyburd/redigo/redis" Go语言Redis客户端的简单示例 连 ...
- 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器
一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...
- C语言中的基础知识变量探讨
C语言中的变量是编程的基础,主要有四个要素:存储类型.存储大小.存储名称和存储地址. 一.变量的要素: 1.存储类型:主要表明名变量存储的特征,主要有auto.extern.static和regist ...
- laravel基础课程---3、路由(Laravel中的常见路由有哪几种)
laravel基础课程---3.路由(Laravel中的常见路由有哪几种) 一.总结 一句话总结: 6种:post,get,put,patch,delete,options Route::get($u ...
- OC基础教程 C语言中的格式占位符:
C语言中的格式占位符: %a,%A 读入一个浮点值(仅C99有效) %c 读入一个字符 %d 读入十进制整数 %i 读入十进制,八进制,十六进制整数 %o 读入八进制整数 %x,%X 读入十六进制整数 ...
- C++基础 (8) 第八天 数组指针 模板指针 C语言中的多态 模板函数
1昨日回顾 2 多态的练习-圆的图形 3多态的练习-程序员薪资 4员工管理案例-抽象类和技术员工的实现 employee.h: employee.cpp: technician.h: technici ...
- 编程基础-c语言中指针、sizeof用法总结
1.指针 学习 C 语言的指针既简单又有趣.通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的.所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的. ...
- Java语言中的面向对象特性总结
Java语言中的面向对象特性 (总结得不错) [课前思考] 1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类? 2. 面向对象编程的特性有哪三个?它们各自又有哪些特性? 3. 你知 ...
- python语言中的编码问题
在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...
随机推荐
- node.js async 几个函数
async.waterfallasync.seriesasync.parallelasync.auto http://my.oschina.net/huangsz/blog/176203http:// ...
- python爬虫1——获取网站源代码(豆瓣图书top250信息)
# -*- coding: utf-8 -*- import requests import re import sys reload(sys) sys.setdefaultencoding('utf ...
- JS - ECMAScript2015(ES6)新特性
友情提示:本文仅mark几个常用的新特性,详细请参见:ES6入门 - ryf: 碎片 var VS let VS const var:声明全局变量, let:声明块级变量,即局部变量 const:声明 ...
- 【hdu6035】 Colorful Tree dfs序
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题目大意:给你一棵树,树上每个节点都有一个颜色. 现在定义两点间的距离为两点最短路径上颜色集合 ...
- Linux CentOS7系统中php安装配置
本篇讲解如何配置php开发环境,让你的php代码可以正常的在网页中运行. 准备工作 linux centos7操作系统 ssh软件 nginx php资源 想要了解更多关于php的内容,请访问: ph ...
- 第6章—渲染web视图—使用Thymeleaf
使用Thymeleaf 长期以来,jsp在视图领域有非常重要的地位,随着时间的变迁,出现了一位新的挑战者:Thymeleaf,Thymeleaf是原生的,不依赖于标签库.它能够在接受原始HTML的地方 ...
- Android 开发工具类 17_setAlarm
Alarm 是在应用程序生命周期之外设置的,所以它们十分适合于调度定时更新或者数据查询,从而避免了在后台持续运行 Service.但触发 Alarm 时,就会广播指定的 Pending Intent. ...
- 全连接层(FC)与全局平均池化层(GAP)
在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,全连接层的每一个节点都与上一层每个节点连接,是把前一层的输出特征都综合起来,所以该层的权值参数是 ...
- [LeetCode]LinkedList Cycle
题目说明 Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without usi ...
- 面试题43:计算多少种译码方式(decode-ways)
这道题是非常典型的DP问题.按照DP的套路,关键是讨论出递推表达式,遍历过程中针对当前字符是否为'0'以及前一个字符为'0',分类讨论得出到目前字符为止最多有多少种译码方式?理清了递推表达式,代码是很 ...