本文详解如何在 Go 中创建 RESTful HTTP 接口,供 AngularJS 通过 $http 或 $resource 调用;核心在于定义路由、解析请求 JSON、执行业务逻辑并返回标准 JSON 响应。
本文详解如何在 go 中创建 restful http 接口,供 angularjs 通过 `$http` 或 `$resource` 调用;核心在于定义路由、解析请求 json、执行业务逻辑并返回标准 json 响应。
要实现 Go 后端与 AngularJS 前端的可靠通信,关键在于
建立清晰、约定一致的 HTTP API 端点(Endpoint)
。AngularJS 并不“主动连接”Go 服务,而是通过 $http.post('/api/users', data) 等方式向 Go 启动的 HTTP 服务器发起标准 HTTP 请求;Go 服务则需监听指定端口、注册对应路径的处理器,并按 REST 规范处理请求与响应。
✅ Go 端:定义可被 AngularJS 调用的 API 路由
Go 使用 net/http 包即可快速搭建轻量 API 服务。以下是一个生产就绪度较高的基础示例(已适配 Go 1.16+,避免使用已弃用的 ioutil):
?
关键点说明
:
/api/ 是 AngularJS 客户端调用的
统一前缀路径
(如 $http.post('/api/users'));
Go 通过 http.HandleFunc("/api/", ...) 将所有以 /api/ 开头的请求交由 apiHandler 处理;
Content-Type: application/json 必须由前端显式设置(AngularJS 默认会发送),后端才可正确解析 r.Body;
所有响应均设置 Content-Type: application/json 并使用 json.Encoder 安全输出,避免字符串拼接引发格式错误。
✅ AngularJS 端:调用 Go 接口的典型写法
⚠️ 注意事项与最佳实践
CORS 支持
:若 Go 服务与 AngularJS 页面不在同一域名/端口(如 localhost:4200 → localhost:8080),需在 Go 中添加 CORS 头:
立即学习
“
前端免费学习笔记(深入)
”;
(生产环境请限制 Allow-Origin 到可信域名)
错误处理一致性
:前后端约定统一响应结构(如含 success, message, data 字段),便于 AngularJS 统一拦截和提示。
路由细化
:实际项目中应按资源拆分路由,如 /api/users, /api/posts,并在 Go 中使用子路由或 http.ServeMux 分发,提升可维护性。
避免 fmt.Fprintln(w, string(jsonBytes))
:该写法易导致额外换行或编码问题;务必使用 json.Encoder 并显式设置状态码与 Header。
通过以上结构,你已建立起一条稳定、可扩展、符合 Web 标准的 Go ↔ AngularJS 数据通道——Go 提供端点,AngularJS 发起请求,JSON 作为唯一数据契约,简洁而强大。
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Response struct {
Success bool `json:"success"`
Message string `json:"message,omitempty"`
Data interface{} `json:"data,omitempty"`
}
func fail(w http.ResponseWriter, message string) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(Response{Success: false, Message: message})
}
func success(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(Response{Success: true, Data: data})
}
// 示例业务结构体
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func doBusinessLogicWithData(data []byte) (*User, error) {
var user User
if err := json.Unmarshal(data, &user); err != nil {
return nil, fmt.Errorf("invalid JSON: %w", err)
}
// 模拟业务逻辑:生成 ID、校验字段等
if user.Name == "" || user.Email == "" {
return nil, fmt.Errorf("name and email are required")
}
user.ID = 123 // 实际中可来自数据库插入
return &user, nil
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
fail(w, "Only POST method is supported")
return
}
// 读取请求体(注意:需设置 Content-Type: application/json)
var requestBody []byte
var err error
if r.Body == nil {
fail(w, "empty request body")
return
}
requestBody, err = io.ReadAll(r.Body)
if err != nil {
fail(w, "failed to read request body: "+err.Error())
return
}
defer r.Body.Close()
// 解析并处理数据
result, err := doBusinessLogicWithData(requestBody)
if err != nil {
fail(w, err.Error())
return
}
// 返回标准化 JSON 响应
success(w, result)
}
func main() {
const serverPort = 8080
http.HandleFunc("/api/", apiHandler)
log.Printf("? Go server starting on http://localhost:%d", serverPort)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", serverPort), nil))
}// AngularJS controller 示例
app.controller('MainCtrl', function($scope, $http) {
$scope.submitUser = function() {
var userData = {
name: $scope.name,
email: $scope.email
};
$http.post('/api/', userData)
.then(function(response) {
if (response.data.success) {
console.log('✅ Created:', response.data.data);
alert('User saved successfully!');
} else {
alert('❌ Error: ' + response.data.message);
}
})
.catch(function(error) {
console.error('Network or server error:', error);
alert('Request failed. Check console.');
});
};
});w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")