
创建HTTP服务仅需几行代码,利用标准库net/http包实现核心功能。建立一个监听8080端口的服务,对所有请求返回"hello, world"响应。
mkdir simple-http-server
cd simple-http-server
go mod init simple-http-server在main.go中写入以下代码:
package main
import "net/http"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
w.Write([]byte("hello, world"))
})
http.ListenAndServe(":8080", nil)
}http.HandleFunc注册路由处理函数,http.ListenAndServe启动服务监听。通过curl测试服务:
curl localhost:8080/项目采用模块化设计,分为HTTP服务器和图书存储两大模块。API遵循RESTful风格,支持图书CRUD操作,数据交互使用JSON格式。
创建项目基础结构:
mkdir bookstore
cd bookstore
go mod init bookstore项目目录布局:
├── cmd/
│ └── bookstore/
│ └── main.go
├── internal/
│ └── store/
│ └── memstore.go
├── server/
│ ├── middleware/
│ │ └── middleware.go
│ └── server.go
└── store/
├── factory/
│ └── factory.go
└── store.go数据存储模块 通过工厂模式创建存储实例,支持多种存储后端。定义通用接口:
type BookStore interface {
Create(*Book) error
Update(*Book) error
Get(string) (*Book, error)
GetAll() ([]*Book, error)
Delete(string) error
}内存存储实现示例:
type memStore struct {
sync.RWMutex
books map[string]*Book
}HTTP服务器模块 封装路由注册和中间件处理:
func NewBookStoreServer(addr string, s store.BookStore) *BookStoreServer {
srv := &BookStoreServer{
addr: addr,
store: s,
}
router := mux.NewRouter()
router.Use(loggingMiddleware)
router.HandleFunc("/book", srv.createBook).Methods("POST")
router.HandleFunc("/book/{id}", srv.updateBook).Methods("PUT")
return srv
}主程序流程 初始化存储和服务器实例,优雅处理服务启停:
func main() {
s, err := factory.New("mem")
srv := server.NewBookStoreServer(":8080", s)
errChan := make(chan error)
go func() { errChan <- srv.ListenAndServe() }()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
select {
case err := <-errChan:
log.Printf("Server error: %v", err)
case <-quit:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)
}
}gorilla/mux实现路由匹配示例API请求:
POST /book
Content-Type: application/json
{"id":"978-3-16-148410-0","name":"Go语言设计模式","authors":["张三"],"press":"人民邮电出版社"}响应处理逻辑:
func (bs *BookStoreServer) createBook(w http.ResponseWriter, req *http.Request) {
var book store.Book
if err := json.NewDecoder(req.Body).Decode(&book); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := bs.store.Create(&book); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
}