最近在写一些 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 接口非常简单,只有一个方法,这个方法接受两个参数,分别是 ResponseWriteRequest;这也就是说只要一个结构体实现了 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 路由基础的更多相关文章

  1. 在Go语言中基础的Redis操作

    在Go语言中基础的Redis操作 需要先安装redigo go get "github.com/garyburd/redigo/redis" Go语言Redis客户端的简单示例 连 ...

  2. 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器

    一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...

  3. C语言中的基础知识变量探讨

    C语言中的变量是编程的基础,主要有四个要素:存储类型.存储大小.存储名称和存储地址. 一.变量的要素: 1.存储类型:主要表明名变量存储的特征,主要有auto.extern.static和regist ...

  4. laravel基础课程---3、路由(Laravel中的常见路由有哪几种)

    laravel基础课程---3.路由(Laravel中的常见路由有哪几种) 一.总结 一句话总结: 6种:post,get,put,patch,delete,options Route::get($u ...

  5. OC基础教程 C语言中的格式占位符:

    C语言中的格式占位符: %a,%A 读入一个浮点值(仅C99有效) %c 读入一个字符 %d 读入十进制整数 %i 读入十进制,八进制,十六进制整数 %o 读入八进制整数 %x,%X 读入十六进制整数 ...

  6. C++基础 (8) 第八天 数组指针 模板指针 C语言中的多态 模板函数

    1昨日回顾 2 多态的练习-圆的图形 3多态的练习-程序员薪资 4员工管理案例-抽象类和技术员工的实现 employee.h: employee.cpp: technician.h: technici ...

  7. 编程基础-c语言中指针、sizeof用法总结

    1.指针 学习 C 语言的指针既简单又有趣.通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的.所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的. ...

  8. Java语言中的面向对象特性总结

    Java语言中的面向对象特性 (总结得不错) [课前思考]  1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?  2. 面向对象编程的特性有哪三个?它们各自又有哪些特性?  3. 你知 ...

  9. python语言中的编码问题

    在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...

随机推荐

  1. PHP 单点登录实现方案

    单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...

  2. php主要用于哪几方面

    1,服务端脚本,网站和web应用程序,web服务器,php解析器,web浏览器 2,命令行脚本 3,编写桌面应用程序

  3. ifconfig-dropped

    drop的包是因为网卡的buffer满了 查看当前网卡的buffer size情况 ethtool -g eth0 Ring parameters for eth0: Pre-set maximums ...

  4. 在vue项目中安装使用Mint-UI

    一.Mint UI 是 由饿了么前端团队推出的 一个基于 Vue.js 的移动端组件库,具有以下特性:       使用文档: http://mint-ui.github.io/#!/zh-cn Mi ...

  5. js的let语句在安卓手机端的QQ浏览器出错的问题

    关于JavaScript里面的let,let 语句可以声明一个块级作用域的本地变量,并且可选的将其初始化为一个值. <ul id="list"> </ul> ...

  6. 【xsy1232】Magic 最小割

    题目大意:给你一个$n$个点,$m$条有向边的图,每个点有一个点权$a_i$,同时你可以用$b_i$的代价将$a_i$变为$0$ 另外你要付出$\sum\limits_{i=1}^n\max\limi ...

  7. tensorflow训练了10万次,运行完毕,对这个word2vec终于有点感觉了

    tensorflow训练了10万次,运行完毕,对这个word2vec终于有点感觉了 感觉它能找到词与词之间的关系,应该可以用来做推荐系统.自动摘要.相关搜索.联想什么的 tensorflow1.1.0 ...

  8. 剑指offer五十五之链表中环的入口结点

    一.题目 一个链表中包含环,请找出该链表的环的入口结点. 二.思路 方法一: 假设x为环前面的路程(黑色路程),a为环入口到相遇点的路程(蓝色路程,假设顺时针走), c为环的长度(蓝色+橙色路程). ...

  9. CS231n学习笔记-图像分类笔记(下篇)

    原文地址:智能单元 K-Nearest Neighbor分类器 大家可能注意到了,为什么只用最相似的一张图片的标签来作为测试图像的标签呢?这不是很奇怪吗!是的,使用K-Nearest Neighbor ...

  10. Linux 系统计算文件夹下文件数量数目

    查看某目录下文件的个数(未包括子目录) ls -l |grep "^-"|wc -l 或 find ./company -type f | wc -l 查看某目录下文件的个数,包括 ...