最近在写一些 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. jzoj5805

    #include<bits/stdc++.h> using namespace std; int x,n,pp,ct[10000]; long double f[210][(1<&l ...

  2. (进阶篇)PHP(thinkphp5框架)实现用户注册后邮箱验证,激活帐号

    本文将结合实例,讲解如何使用thinkphp5+Mysql完成注册帐号.发送激活邮件.验证激活帐号.处理URL链接过期的功能. 业务流程 1.用户提交注册信息. 2.写入数据库,此时帐号状态未激活. ...

  3. POJ 2377

    #include<stdio.h> #define MAXN 1005 #include<iostream> #include<algorithm> #define ...

  4. Winform—C#读写config配置文件

    现在FrameWork2.0以上使用的是:ConfigurationManager或WebConfigurationManager.并且AppSettings属性是只读的,并不支持修改属性值. 一.如 ...

  5. LruCache源码分析

    LRU(Least Recently Used)是一种很常用的资源调度策略,与20/80原则契合,在资源达到上限时倾向保留最近经常访问的资源对象. Android中基于LRU实现了缓存对象,即LruC ...

  6. Spring Security构建Rest服务-0801-短信验证码发送

    实现短信验证码登录 开发短信验证码接口 校验短信验证码并登录 短信验证码和图片验证码开发思路类似: 1,我们访问一个controller 2,在controller里调用短信验证码生成接口生成验证码 ...

  7. wp-postviews使用方法

    1.安装 2.头部引用<?php wp_head(); ?> 3.文章调用:<?php if(function_exists('the_views')) { the_views(); ...

  8. Cocos2d-x游戏导出android工程,提取cocos的so文件

      Cocos2d-x游戏导出android工程,提取cocos的so文件   原本cocos游戏的android工程编译时,需要将cocos的库文件进行编译,这些文件大部分是cpp文件, 使用ndk ...

  9. GBDT多分类示例

    相当于每次都是用2分类,然后不停的训练,最后把所有的弱分类器来进行汇总 样本编号 花萼长度(cm) 花萼宽度(cm) 花瓣长度(cm) 花瓣宽度 花的种类 1 5.1 3.5 1.4 0.2 山鸢尾 ...

  10. JVM笔记6-垃圾回收器

    JVM进行垃圾回收时要考虑哪的问题如下: 1.如何判定对象为垃圾对象? 1.引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,引用失效的时候,计数器的值就-1, ...