golang开发流程及注意事项
1、开发流程
1.1. 复杂框架类服务架构流程
明确整个业务流程
划分独立处理模块,弄清楚那些模块会出现并发
明确基本数据结构
a、request
b、response
c、error错误处理抽象接口
针对接口编程,我们必须的定义好每一个环节的接口,这里有一个点必须的注意:就是我们在实现接口的时候,NewXXX()获取实现结构类型的返回值必须是借口对象,便于统一处理明确调度器的职责
中间件
a、各个独立模块之间如何通信,如何统一管理各个木块之间的通道,通道管理器
b、如何让各个独立模块统一听从调度器的调度,停止信号处理器、contex包的使用
c、独立模块的管理和限流,实体池
d、统一的实体标记管理,Id生成器
注意:这里有一个限流的问题,一般情况下,我们为解决并发性能问题,都有可能限制客户端的访问数量,但是我们又不可能不去处理超出我们限制的客户请求,因此,对于客户请求,我们一般可以优先放在我们内部的存储器内,定时的把这些请求刷新到通道管理器中独立处理模块的实现
1.2. Api开发流程
错误码、错误数据结构
b、正确的响应数据模型
正确相应编码,以及数据结构
c、请求Request参数接收数据结构
d、业务数据模型
- 设计错误日志处理方式
- 数据库操作、orm设计
- 业务逻辑代码编写
- 单元测试
1.3. Api的设计原则
Restful风格
https://github.com/git
https://github.com/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08
URI设计上的一些技巧:
a、使用_或-来让URI可读性更好
b、使用/来表示资源的层级关系
c、使用?用来过滤资源
d、,或;可以用来表示同级资源的关系
200(OK) - 表示已在响应中发出
204(无内容) - 资源有空表示
301(Moved Permanently) - 资源的URI已被更新
303(See Other) - 其他(如,负载均衡)
304(not modified)- 资源未更改(缓存)
400 (bad request)- 指代坏请求(如,参数错误)
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务端当前无法处理请求
b、POST 使用服务端管理的(自动产生)的实例号创建资源、创建子资源、部分更新资源
200(OK)- 如果现有资源已被更改
201(created)- 如果新资源被创建
202(accepted)- 已接受处理请求但尚未完成(异步处理)
301(Moved Permanently)- 资源的URI被更新
303(See Other)- 其他(如,负载均衡)
400(bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务当前无法处理请求
c、PUT 用客户端管理的实例号创建一个资源、通过替换的方式更新资源
200 (OK)- 如果已存在资源被更改
201 (created)- 如果新资源被创建
301(Moved Permanently)- 资源的URI已更改
303 (See Other)- 其他(如,负载均衡)
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
406 (not acceptable)- 服务端不支持所需表示
409 (conflict)- 通用冲突
412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务当前无法处理请求
d、DELETE 删除资源
200 (OK)- 资源已被删除
301 (Moved Permanently)- 资源的URI已更改
303 (See Other)- 其他,如负载均衡
400 (bad request)- 指代坏请求
404 (not found)- 资源不存在
409 (conflict)- 通用冲突
500 (internal server error)- 通用错误响应
503 (Service Unavailable)- 服务端当前无法处理请求
GET: https://api.github.com/args/github
Accept: application/json
b、Response
HTTP/1.1 200 OK
Content-Type:application/json
http://api.example.com/1.0/foo
Accept: vnd.example-com.foo+json; version=1.0
Accept: application/vnd.github.v3
2、字符串
2.1. 比较字符串
进行比较操作时会产生三个问题:
a、有些Unicode编码的字符可以用两个或者多个不同的字节序列来表示
b、有些情况下用户希望把不同的字符看成相同的字符,如:搜索相关
c、有些字符序列和语言相关,如:中文和英文不一样
2.2. 字符和字符串
var s string = "hello world!"
c := []rune(s)
s = string(c)
//1、使用+=
s := "hello"
b := " world!"
s += b
//2、使用strings.Join()函数,比+=更有效
s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ", "))
//3、使用bytes.Buffer,比 += 和join更有效
s := "hello"
b := " world!"
var buffer bytes.Buffer
buffer.WriteString(s)
buffer.WriteString(b)
buffer.String()
//1、使用[]rune(s)转换为unicode字符在根据索引取值
//2、使用strings包和unicode包、utf8包
line L= "dffh jj wr发生 大幅度 发t yj fd"
i := strings.IndexFunc(line, unicode.IsSpace)
firstWord := line[:i]
i := strings.LastIndexFunc(line, unicode.IsSpace)
_, size := utf8.DecodeRuneInstring(line[j:])
lastWord := line(j+size:)
fmt.Println(firstWord, lastWord)
3、集合类型
3.1. 值、指针、引用类型
值
变量持有相应的值,在传递给方法或者函数的时候会被复制一次指针
a、因为go语言是基于值传递的方式传递参数的,因此,对于传递比较大的数据对象时,我们可以改为传递指针,使得参数的传递成本最低,并且内容可以修改
b、当我们需要在一个函数或方法中返回三个及以上值的时候,如果这些值是同一类型,我们最好使用一个切片来传递;如果值类型各异,我们最好传递一个指向结构的指针。
注意:指针也可以指向一个引用类型,但只对切片有用
通道、函数、方法、映射、切片、interface接口类型