在本教程中,我们将使用 GoFr 构建一个简单的摩尔斯电码翻译 API。GoFr 是一个旨在简化微服务开发的框架,非常适合构建轻量级、易于部署、管理和监控的 API。如果你对 GoFr 或 Go 语言还不熟悉,这是一个很好的入门方式。
什么是 GoFr?
GoFr 是一个专为构建微服务而设计的 Go 框架。它提供开箱即用的 Kubernetes 支持,是云原生应用程序的理想选择。借助内置的可观测性功能,GoFr 确保你可以轻松监控和调试服务。
前提条件
在开始之前,请确保你已安装以下工具:
Go(版本 1.21 或更高) 文本编辑器或 IDE(如 VS Code 等)
实现步骤
初始化 Go 模块
首先,为你的项目创建一个新目录并进入该目录。然后使用以下命令初始化一个新的 Go 模块:
go mod init morse-translator
这将创建一个 go.mod
文件,用于定义你的 Go 项目及其依赖项。
安装 GoFr
GoFr 是我们用于创建 API 的核心框架。你可以通过运行以下命令添加 GoFr 依赖:
go get gofr.dev
这将下载并安装 GoFr 包,使其可用于你的项目。你还需要运行以下命令以确保所有依赖项同步:
go mod tidy
包导入
package main
import (
"strings"
"gofr.dev/pkg/gofr"
)
在这个代码块中,我们导入了必要的包:
strings
:用于字符串操作。gofr.dev/pkg/gofr
:这是 GoFr 框架。
文本与摩尔斯电码的映射
var textToMorseMap = map[rune]string{
'A': ".-", 'B': "-...", 'C': "-.-.", 'D': "-..", 'E': ".", 'F': "..-.",
'G': "--.", 'H': "....", 'I': "..", 'J': ".---", 'K': "-.-", 'L': ".-..",
'M': "--", 'N': "-.", 'O': "---", 'P': ".--.", 'Q': "--.-", 'R': ".-.",
'S': "...", 'T': "-", 'U': "..-", 'V': "...-", 'W': ".--", 'X': "-..-",
'Y': "-.--", 'Z': "--..", '1': ".----", '2': "..---", '3': "...--",
'4': "....-", '5': ".....", '6': "-....", '7': "--...", '8': "---..",
'9': "----.", '0': "-----", ' ': "/", '.': ".-.-.-", ',': "--..--",
'?': "..--..", '!': "-.-.--", '/': "-..-.", '(': "-.--.", ')': "-.--.-",
'&': ".-...", ':': "---...", '=': "-...-", '+': ".-.-.", '-': "-....-",
'"': ".-..-.", '@': ".--.-.",
}
var morseToTextMap = make(map[string]rune)
textToMorseMap
是一个将字符转换为摩尔斯电码的映射。morseToTextMap
是一个反向映射,用于将摩尔斯电码转换回字符。这将在 init()
函数中填充。
func init() {
for key, value := range textToMorseMap {
morseToTextMap[value] = key
}
}
init()
函数在程序启动时会自动调用,用于初始化变量或设置任务。在这里,我们遍历 textToMorseMap
并填充 morseToTextMap
,以便每个摩尔斯电码序列都能映射回相应的字符。
文本到摩尔斯电码的转换
func toMorseCode(text string) string {
text = strings.TrimSpace(text)
var result []string
for _, char := range strings.ToUpper(text) {
if code, exists := textToMorseMap[char]; exists {
result = append(result, code)
} else {
result = append(result, "❓")
}
}
return strings.Join(result, " ")
}
此函数将文本转换为摩尔斯电码。我们首先去除输入文本中的多余空格,然后将每个字符转换为大写(因为摩尔斯电码不区分大小写)。对于每个字符,我们检查其是否存在于 textToMorseMap
中。如果存在,则将其摩尔斯电码附加到结果中;否则,附加符号“❓”以指示未知字符。
摩尔斯电码到文本的转换
func fromMorseCode(morse string) string {
morseSymbols := strings.Fields(morse)
var result []string
for _, symbol := range morseSymbols {
if decodedChar, exists := morseToTextMap[symbol]; exists {
result = append(result, string(decodedChar))
} else {
result = append(result, "❓")
}
}
return strings.Join(result, "")
}
此函数将摩尔斯电码转换为文本。首先,我们使用 strings.Fields(morse)
将摩尔斯电码字符串拆分为单个摩尔斯电码单元,以空格作为分隔符,分隔每个字符的摩尔斯电码。对于每个符号,我们检查其是否存在于 morseToTextMap
中。如果存在,则将解码后的字符附加到结果中;否则,附加符号“❓”以指示未知字符。
API 初始化和设置
func main() {
app := gofr.New()
}
这将创建一个新的 GoFr 应用程序(app
),用于处理 API 的 HTTP 请求。
定义 API 路由
func main() {
// 其他代码
app.GET("/text-to-morse", func(ctx *gofr.Context) (interface{}, error) {
text := ctx.Request.Param("text")
if text == "" {
return map[string]string{
"status": "400",
"error": "400 Bad Request",
"text": "No text provided.",
}, nil
}
morse := toMorseCode(text)
return map[string]interface{}{
"status": "200",
"text": text,
"morse": morse,
"instructions": map[string]string{
".": "Dit (short beep)",
"-": "Dah (long beep)",
"/": "Space between words (pause)",
"❓": "Unknown character",
},
}, nil
})
}
这个端点(/text-to-morse
)从请求中接收一个文本查询参数。如果文本为空,则返回 400 Bad Request 错误。否则,它调用 toMorseCode
函数将文本转换为摩尔斯电码,并在响应中返回结果及一些说明。
func main() {
// 其他代码
app.GET("/morse-to-text", func(ctx *gofr.Context) (interface{}, error) {
morse := ctx.Request.Param("morse")
if morse == "" {
return map[string]string{
"status": "400",
"error": "400 Bad Request",
"text": "No Morse code provided.",
}, nil
}
text := fromMorseCode(morse)
return map[string]interface{}{
"status": "200",
"morse": morse,
"text": text,
"instructions": map[string]string{
"❓": "Unknown character",
},
}, nil
})
}
类似地,这个端点(/morse-to-text
)接收一个摩尔斯电码查询参数。如果摩尔斯电码参数为空,则返回 400 Bad Request 错误。否则,它调用 fromMorseCode
将摩尔斯电码转换回文本,并在响应中返回结果。
运行应用程序
func main() {
// 其他代码
app.Run()
}
app.Run()
启动服务器在端口 8000 上监听传入请求。
结果
服务器运行后,你可以使用 Postman 或 curl 等工具测试 API。
文本到摩尔斯电码:发送 GET 请求到
http://localhost:8000/text-to-morse?text=hi this is pratham
{
"data": {
"instructions": {
"-": "Dah (long beep)",
".": "Dit (short beep)",
"/": "Space between words (pause)",
"❓": "Unknown character"
},
"text": "hi this is pratham",
"morse": ".... .. / - .... .. ... / .. ... / .--. .-. .- - .... .- --",
"status": "200"
}
}摩尔斯电码到文本:发送 GET 请求到
http://localhost:8000/morse-to-text?morse=.... .. / - .... .. ... / .. ... / .--. .-. .- - .... .- --
{
"data": {
"instructions": {
"❓": "Unknown character"
},
"morse": ".... .. / - .... .. ... / .. ... / .--. .-. .- - .... .- --",
"status": "200",
"text": "HI THIS IS PRATHAM"
}
}
完整代码
package main
import (
"strings"
"gofr.dev/pkg/gofr"
)
var textToMorseMap = map[rune]string{
'A': ".-", 'B': "-...", 'C': "-.-.", 'D': "-..", 'E': ".", 'F': "..-.",
'G': "--.", 'H': "....", 'I': "..", 'J': ".---", 'K': "-.-", 'L': ".-..",
'M': "--", 'N': "-.", 'O': "---", 'P': ".--.", 'Q': "--.-", 'R': ".-.",
'S': "...", 'T': "-", 'U': "..-", 'V': "...-", 'W': ".--", 'X': "-..-",
'Y': "-.--", 'Z': "--..", '1': ".----", '2': "..---", '3': "...--",
'4': "....-", '5': ".....", '6': "-....", '7': "--...", '8': "---..",
'9': "----.", '0': "-----", ' ': "/", '.': ".-.-.-", ',': "--..--",
'?': "..--..", '!': "-.-.--", '/': "-..-.", '(': "-.--.", ')': "-.--.-",
'&': ".-...", ':': "---...", '=': "-...-", '+': ".-.-.", '-': "-....-",
'"': ".-..-.", '@': ".--.-.",
}
var morseToTextMap = make(map[string]rune)
func init() {
for key, value := range textToMorseMap {
morseToTextMap[value] = key
}
}
func toMorseCode(text string) string {
text = strings.TrimSpace(text)
var result []string
for _, char := range strings.ToUpper(text) {
if code, exists := textToMorseMap[char]; exists {
result = append(result, code)
} else {
result = append(result, "❓")
}
}
return strings.Join(result, " ")
}
func fromMorseCode(morse string) string {
morseSymbols := strings.Fields(morse)
var result []string
for _, symbol := range morseSymbols {
if decodedChar, exists := morseToTextMap[symbol]; exists {
result = append(result, string(decodedChar))
} else {
result = append(result, "❓")
}
}
return strings.Join(result, "")
}
func main() {
app := gofr.New()
app.GET("/text-to-morse", func(ctx *gofr.Context) (interface{}, error) {
text := ctx.Request.Param("text")
if text == "" {
return map[string]string{
"status": "400",
"error": "400 Bad Request",
"text": "No text provided.",
}, nil
}
morse := toMorseCode(text)
return map[string]interface{}{
"status": "200",
"text": text,
"morse": morse,
"instructions": map[string]string{
".": "Dit (short beep)",
"-": "Dah (long beep)",
"/": "Space between words (pause)",
"❓": "Unknown character",
},
}, nil
})
app.GET("/morse-to-text", func(ctx *gofr.Context) (interface{}, error) {
morse := ctx.Request.Param("morse")
if morse == "" {
return map[string]string{
"status": "400",
"error": "400 Bad Request",
"text": "No Morse code provided.",
}, nil
}
text := fromMorseCode(morse)
return map[string]interface{}{
"status": "200",
"morse": morse,
"text": text,
"instructions": map[string]string{
"❓": "Unknown character",
},
}, nil
})
app.Run()
}
通过 GoFr,我们快速构建了一个简单的文本到摩尔斯电码和摩尔斯电码到文本的 API,展示了该框架在创建微服务时的易用性。其简洁的设置和内置功能简化了开发过程,是快速创建微服务的绝佳选择。虽然这只是一个基础示例,但 GoFr 可以扩展到更复杂的应用程序。