在CRUD应用中使用Golang是否可行?
在CRUD应用中使用Golang是否可行? 我经营一家货运经纪公司,我们通过开发自己的自动化软件来实现专业化自动化。货运经纪公司的“操作系统”是运输管理系统,这类系统与客户关系管理系统共享许多相同的对象,并且通常与后者捆绑在一起。由于需要快速搭建系统,我最初在Salesforce平台上使用APEX开发了我们的第一个运输管理系统。
在准备开发第二个版本的运输管理系统+客户关系管理系统(我们将进行本地部署)时,我尝试了许多编程语言和开源软件。我对几乎所有用Go语言编写的软件的速度和效率印象深刻,然而我尚未发现任何客户关系管理系统或知名的增删改查应用程序在后端使用Go。
由于我之前从未使用Go编程过,我不得不问:考虑使用Go语言来构建我们的运输管理系统+客户关系管理系统,并搭配像HTMX和“原生”JavaScript这样简单的前端技术,是否可行?
更多关于在CRUD应用中使用Golang是否可行?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
哈哈,是啊,这个行业会考验你对人性的耐心。
我老是听说Templ,我会去看看的。
更多关于在CRUD应用中使用Golang是否可行?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
亲爱的朋友,
任何使用第三方组件的前端开发者都可以。后端使用 Go 语言、Node.js 或 Free Pascal,你就能构建任何类型的应用程序。
考虑到您需要进行大量的数据库增删改查操作,请使用Go语言的数据库框架——Gorm(https://gorm.io/)。它将为您节省大量时间,并使您的代码保持整洁,易于维护。
完全可以用Go语言编写那个应用程序。你可以先查看开始学习 - Go编程语言中的学习章节,特别是Web开发链接(https://gowebexamples.com/)。
嘿,Dean,
抱歉回复晚了。我唯一了解的语言是 HTML、Visual Basic(笑)、C++、Python,最近还用 Next.js 建了一个网站(但我正努力远离 JavaScript 的复杂性)。我从 1995 年编程到 2002 年,然后在 2022 年重新开始。
我最初的想法是 Laravel,因为它开箱即用,而且看起来足够简单,但我对 Go 了解得越多,就越想学习它。我明白它并非“开箱即用”,但它看起来并不复杂,并且有一个社区支持的 Supabase 库,我打算用它来连接 Postgres/TimescaleDB。
TMS 系统需要很多模块/插件,所以我想我会用 Go、HTMX 和 Tailwind 构建一个简单的。这个模块具体是用来手动记录半挂车的进出库状态的。
我认为这正是Go语言能大放异彩的用例。我自己就用Go作为后端交付过很多CRUD应用。我虽然没有用过HTMX,但Go+HTMX的组合普遍评价很高:
你还在考虑哪些其他选项?如果我是你,我会创建一个概念验证,用几种不同的技术来试试水。
我的背景是数据和报表。如今,人们会称我为数据工程师/数据分析师。我常常把学习一门新的编程语言或新技能当作一种爱好。去年是木工,花费不菲,所以今年又回到了编程。我已经用Go做过几个小规模的CRUD应用。我即将完成一个使用Go、Templ和HTMX,并以SQL Server作为后端的应用。SQL Server运行在Docker容器中。如果我能用Go做出一个看起来糟糕的HTMX前端,那么你完全可以做一个TMS(运输管理系统)。这个想法引起了我的注意,因为我妻子从事物流和运输工作已经很多年了。当我和她都在家办公时,我常常听到她与卡车司机、港口和货运经纪人进行的单方面对话。我看到了她完全不同的一面,因为当人们不履行职责时,她会从一个甜美无辜的小狗瞬间变成一头顶级的阿尔法狼。总之,我的建议是开始时保持简单,随着学习的深入,你可以发挥更多创意。
在CRUD应用中使用Golang是完全可行的,甚至可以说是优秀的选择。Go语言的标准库提供了强大的HTTP服务器和数据库支持,非常适合构建高性能的后端系统。以下是一个简单的示例,展示如何使用Go构建一个基本的CRUD API:
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
)
type Shipment struct {
ID string `json:"id"`
From string `json:"from"`
To string `json:"to"`
Status string `json:"status"`
}
var shipments []Shipment
func getShipments(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(shipments)
}
func getShipment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r)
for _, item := range shipments {
if item.ID == params["id"] {
json.NewEncoder(w).Encode(item)
return
}
}
json.NewEncoder(w).Encode(&Shipment{})
}
func createShipment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var shipment Shipment
_ = json.NewDecoder(r.Body).Decode(&shipment)
shipment.ID = "3" // 实际应用中应使用UUID
shipments = append(shipments, shipment)
json.NewEncoder(w).Encode(shipment)
}
func updateShipment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r)
for index, item := range shipments {
if item.ID == params["id"] {
shipments = append(shipments[:index], shipments[index+1:]...)
var shipment Shipment
_ = json.NewDecoder(r.Body).Decode(&shipment)
shipment.ID = params["id"]
shipments = append(shipments, shipment)
json.NewEncoder(w).Encode(shipment)
return
}
}
json.NewEncoder(w).Encode(shipments)
}
func deleteShipment(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r)
for index, item := range shipments {
if item.ID == params["id"] {
shipments = append(shipments[:index], shipments[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(shipments)
}
func main() {
router := mux.NewRouter()
// 初始化一些示例数据
shipments = append(shipments, Shipment{ID: "1", From: "New York", To: "Los Angeles", Status: "In Transit"})
shipments = append(shipments, Shipment{ID: "2", From: "Chicago", To: "Miami", Status: "Delivered"})
router.HandleFunc("/shipments", getShipments).Methods("GET")
router.HandleFunc("/shipments/{id}", getShipment).Methods("GET")
router.HandleFunc("/shipments", createShipment).Methods("POST")
router.HandleFunc("/shipments/{id}", updateShipment).Methods("PUT")
router.HandleFunc("/shipments/{id}", deleteShipment).Methods("DELETE")
log.Fatal(http.ListenAndServe(":8000", router))
}
对于数据库集成,可以使用Go的标准数据库接口:
import (
"database/sql"
_ "github.com/lib/pq"
)
func connectDB() *sql.DB {
connStr := "user=postgres dbname=tms sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
return db
}
func getShipmentsFromDB(db *sql.DB) ([]Shipment, error) {
rows, err := db.Query("SELECT id, from_location, to_location, status FROM shipments")
if err != nil {
return nil, err
}
defer rows.Close()
var shipments []Shipment
for rows.Next() {
var s Shipment
err := rows.Scan(&s.ID, &s.From, &s.To, &s.Status)
if err != nil {
return nil, err
}
shipments = append(shipments, s)
}
return shipments, nil
}
Go语言在并发处理方面的优势特别适合运输管理系统这类需要处理大量并发请求的场景。Go的goroutine可以轻松处理数千个并发连接,而内存占用相对较低。
对于前端集成,HTMX与Go后端配合良好。以下是一个简单的HTML示例:
<!DOCTYPE html>
<html>
<body>
<div id="shipments">
<!-- 货运列表将通过HTMX动态加载 -->
</div>
<button hx-get="/shipments" hx-target="#shipments">
加载货运数据
</button>
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
</body>
</html>
Go的标准库html/template包可以方便地渲染HTML模板:
func renderShipments(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("shipments.html"))
tmpl.Execute(w, shipments)
}
虽然目前可能没有太多知名的CRM/TMS系统公开使用Go作为后端,但这更多是由于历史技术选择而非技术限制。实际上,许多企业级应用正在转向Go,包括PayPal、Uber、Twitch等公司都在关键系统中使用Go。
Go的编译型特性、静态类型检查、优秀的并发支持和简洁的语法使其特别适合构建需要长期维护的企业应用。对于运输管理系统+客户关系管理系统这种需要高性能、高并发处理能力的应用,Go是一个值得考虑的选项。


