Golang中如何将URL参数值存储为任意数据类型的最佳实践

Golang中如何将URL参数值存储为任意数据类型的最佳实践 不知道如何在标题中解释,所以我想实现的基本目标是:

我正在创建一个小型的键值存储项目,但希望能够通过URL存储任意数据类型(通过图形界面是否会更简单?)。例如…当你输入 /Dog/Zeus 时,它会将其保存为 Dog: "Zeus"(字符串)…但当我输入 /Cash/1000 时,它会将其保存为 Cash: 1000(整数)。目前,我的代码只是将条目保存为字符串。我需要支持任意数据类型。

完整代码:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

var data map[string][]string

func main() {
	data = map[string][]string{}

	r := mux.NewRouter()

	r.HandleFunc("/keys", handleDisplay).Methods("GET")
	r.HandleFunc("/keys/{key}", handleDisplay).Methods("GET")
	r.HandleFunc("/updatekey/{key}/{newkey}", handleUpdate).Methods("PUT")

映射:

var data map[string][]string

处理函数:

	r.HandleFunc("/keys", handleDisplay).Methods("GET")
r.HandleFunc("/keys/{key}", handleDisplay).Methods("GET")
r.HandleFunc("/updatekey/{key}/{newkey}", handleUpdate).Methods("PUT")
r.HandleFunc("/update/{key}/{value}/{newvalue}", handleUpdate).Methods("PUT")
r.HandleFunc("/insert/{key}/{value}", handleCreate).Methods("POST")
r.HandleFunc("/delete/{key}", handleDelete).Methods("DELETE")
r.HandleFunc("/delete/{key}/{value}", handleDelete).Methods("DELETE")

显示、创建和更新函数:

func handleDisplay(w http.ResponseWriter, r *http.Request) {

params := mux.Vars(r)

k := params["key"]

if k != "" {
	for item := range data {
		if item == k {
			for _, value := range data[k] {
				fmt.Fprintf(w, "KEY: %v: VALUE: %v\n", k, value)
			}
		}
	}
} else {
	for item := range data {
		for _, value := range data[item] {
			fmt.Fprintf(w, "KEY: %v: VALUE: %v\n", item, value)
		}
	}
}
}

func handleUpdate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)

k := params["key"]
v := params["value"]
nv := params["newvalue"]
nk := params["newkey"]

if v == "" && nv == "" {
	if val, ok := data[k]; ok {
		data[nk] = val
		delete(data, k)
		fmt.Fprintf(w, "KEY: %v has been updated with new KEY: %v", k, nk)
	} else {
		fmt.Fprintf(w, "The KEY: %v doesn't exist", k)
	}
} else {
	if _, ok := data[k]; ok {
		for i := range data[k] {
			data[k] = append(data[k][:i], data[k][i+1:]...)
		}
		data[k] = append(data[k], nv)
		fmt.Fprintf(w, "KEY: %v: VALUE: %v has been updated with Value: %v", k, v, nv)
	} else {
		fmt.Fprintf(w, "KEY: %s doesn't exist", k)
	}
}
}

func handleCreate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)

k := params["key"]
v := params["value"]

data[k] = append(data[k], v)
fmt.Fprintf(w, "KEY: %v: VALUE: %v was inserted into the key-value store successfully", k, v)
}

更多关于Golang中如何将URL参数值存储为任意数据类型的最佳实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

我知道这不是最佳实践……但出于测试目的和方便性考虑,我决定根据CRUD功能来命名它们。

更多关于Golang中如何将URL参数值存储为任意数据类型的最佳实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这并不完全是我想要的功能。我需要解析URL中输入的值,判断该值是布尔值、整数还是字符串,然后相应地存储它们。

你好

将它们存储为字符串以外的类型有什么优势吗?在使用GET方法返回时,最终还是要将它们转换成字符串。

如果你需要的话,可以尝试使用 https://golang.org/pkg/strconv/ 这个包,先尝试转换为布尔值,然后是整数、浮点数,如果都不成功就保留为字符串格式。

只是一个观察,在CRUD操作中不需要在路由中使用方法名 😉

featured-image-large

RESTful API设计:最佳实践概要

Philipp Hauer’s Blog – 4 Mar 15

设计HTTP和RESTful API的最佳实践。介绍URL结构、HTTP方法、关系处理、分页和版本控制。

我以为可以这样做:https://goplay.space/#2BKtalFyGXl

package main

import (
	"fmt"
	"strconv"
)

func parseValue(s string) interface{} {
	b, err := strconv.ParseBool(s)
	if err == nil {
		return b
	}
	i, err := strconv.ParseInt(s, 10, 64)
	if err == nil {
		return i
	}
	f, err := strconv.ParseFloat(s, 64)
	if err == nil {
		return f
	}
	return s
}

func main() {
	v := parseValue("false")
	fmt.Printf("%T %#v\n", v, v)
	v = parseValue("33")
	fmt.Printf("%T %#v\n", v, v)
	v = parseValue("3.14")
	fmt.Printf("%T %#v\n", v, v)
	v = parseValue("hello")
	fmt.Printf("%T %#v\n", v, v)

}

在Golang中处理URL参数并存储为任意数据类型,最佳实践是使用interface{}类型来存储值,并在解析时进行类型推断。以下是改进方案:

首先修改数据结构:

var data map[string][]interface{}

然后创建类型推断函数:

func parseValue(valueStr string) interface{} {
    // 尝试解析为整数
    if intVal, err := strconv.Atoi(valueStr); err == nil {
        return intVal
    }
    
    // 尝试解析为浮点数
    if floatVal, err := strconv.ParseFloat(valueStr, 64); err == nil {
        return floatVal
    }
    
    // 尝试解析为布尔值
    if boolVal, err := strconv.ParseBool(valueStr); err == nil {
        return boolVal
    }
    
    // 默认为字符串
    return valueStr
}

更新处理函数:

func handleCreate(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    
    k := params["key"]
    v := parseValue(params["value"])
    
    data[k] = append(data[k], v)
    fmt.Fprintf(w, "KEY: %v: VALUE: %v (%T) was inserted into the key-value store successfully", k, v, v)
}

func handleDisplay(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    k := params["key"]
    
    if k != "" {
        if values, exists := data[k]; exists {
            for _, value := range values {
                fmt.Fprintf(w, "KEY: %v: VALUE: %v (Type: %T)\n", k, value, value)
            }
        }
    } else {
        for key, values := range data {
            for _, value := range values {
                fmt.Fprintf(w, "KEY: %v: VALUE: %v (Type: %T)\n", key, value, value)
            }
        }
    }
}

func handleUpdate(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    
    k := params["key"]
    v := params["value"]
    nv := parseValue(params["newvalue"])
    nk := params["newkey"]
    
    if v == "" && nv == "" {
        if val, ok := data[k]; ok {
            data[nk] = val
            delete(data, k)
            fmt.Fprintf(w, "KEY: %v has been updated with new KEY: %v", k, nk)
        } else {
            fmt.Fprintf(w, "The KEY: %v doesn't exist", k)
        }
    } else {
        if values, ok := data[k]; ok {
            parsedValue := parseValue(v)
            for i, existingValue := range values {
                if existingValue == parsedValue {
                    data[k][i] = nv
                    fmt.Fprintf(w, "KEY: %v: VALUE: %v has been updated with Value: %v (Type: %T)", k, v, nv, nv)
                    return
                }
            }
        } else {
            fmt.Fprintf(w, "KEY: %s doesn't exist", k)
        }
    }
}

初始化数据结构:

func main() {
    data = make(map[string][]interface{})
    
    r := mux.NewRouter()
    // 路由注册保持不变
    // ...
    
    log.Fatal(http.ListenAndServe(":8080", r))
}

现在系统可以自动识别并存储不同的数据类型:

  • /insert/Cash/1000 会存储为整数 1000
  • /insert/Price/99.99 会存储为浮点数 99.99
  • /insert/Active/true 会存储为布尔值 true
  • /insert/Dog/Zeus 会存储为字符串 “Zeus”

显示时会同时输出值和类型信息,便于调试和使用。

回到顶部