Skip to content

Instantly share code, notes, and snippets.

@kyle-aoki
Last active July 26, 2023 21:27
Show Gist options
  • Save kyle-aoki/52dbb315b25f7bdc669b8239704883db to your computer and use it in GitHub Desktop.
Save kyle-aoki/52dbb315b25f7bdc669b8239704883db to your computer and use it in GitHub Desktop.
An approach to exposing go functions over HTTP
var RawFunctionMap = map[string]func(inputbytes []byte) (outputbytes []byte){}
func ProgramFnRegister[Input any, Output any](fn func(input Input) Output) {
// e.g. "tt/pkg/student.FnCreateStudent"
funcName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
rawFn := func(inputbytes []byte) []byte {
var input Input
if len(inputbytes) != 0 {
check(json.Unmarshal(inputbytes, &input))
}
output := fn(input)
return must(json.Marshal(output))
}
RawFunctionMap[funcName] = rawFn
// POST /tt/pkg/student.FnCreateStudent
http.HandleFunc(fmt.Sprintf("/%s", funcName), func(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Println(funcName, "error:", r)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("%s", r)))
}
}()
inputbytes := must(io.ReadAll(r.Body))
outputbytes := rawFn(inputbytes)
w.Header().Add("Content-Type", "application/json")
w.Write(outputbytes)
})
}
func check(err error) {
if err != nil {
panic(err)
}
}
func must[T any](t T, err error) T {
check(err)
return t
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment