Best way to store values from URL params as arbitrary data types

Hi All,

didn’t know how to explain it in the title, so what I basically want to achieve is:

I’m creating a key-value store as a little project, but want to be able to store any data type via the URL (would it be easier via GUI?). For example… you enter /Dog/Zeus then it would save that to a map as Dog: “Zeus” (string)… but when i enter /Cash/1000 it would save that to a map as Cash: 1000 (int). At the moment, all my code is doing, is saving the entry as a string. I need to allow for arbitrary data types

FULL CODE:

Map:

var data map[string][]string

HandleFunc for the functions:

	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")

Display, Create and Update functions:

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)
}

Hi

Is there any advantage of storing them as anything than string? You will then have to convert them into strings then you deliver them back with the GET methods.

If you want to you could always try to use https://golang.org/pkg/strconv/ and first try to convert to a bool, then int, float and if nothing works just leave it as a string.

Just an observation, in CRUD operations is no need to use method name in the route :wink:

I know it’s not best practice… however for testing purposes and ease I have decided to name them after the CRUD capabilities.

This isn’t really what I’m looking for. I want to parse the values entered in the URL and decide whether the value is a bool, int or string, then store them accordingly.

I thought you could do like this: 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)

}


1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.