类型/名称空间作为HTTP标头

时间:2018-11-26 10:04:41

标签: http go

使用Go或类似语言,假设我们有一个HTTP请求标头,如下所示:

'x-json-body-type': 'FooBarBody'

使用Go可以在地图中查找该类型并使用该结构解码JSON正文吗?

我需要一张结构图,像这样:

m := map[string]*struct{}

如何查找标头x-json-body-type的值,并根据地图中的类型将HTTP请求的正文解码为JSON?

1 个答案:

答案 0 :(得分:1)

由于每个请求很可能需要一个新的struct类型实例,因此您可以创建一个函数映射来初始化并返回该实例,如果要返回不同的值,则函数的返回类型应为interface{}基于标头值的结构类型。

例如:

type (
    Foo struct { /* ... */ }
    Bar struct { /* ... */ }
    Baz struct { /* ... */ }
)

var types = map[string]func() interface{}{
    "Foo": func() interface{}{ return new(Foo) },
    "Bar": func() interface{}{ return new(Bar) },
    "Baz": func() interface{}{ return new(Baz) },
}

要基于请求的标头检索新实例并将json主体解码为其中,您将执行以下操作:

func myHandler(w http.ResponseWriter, r *http.Request) {
    typ := r.Header.Get("x-json-body-type")
    obj := types[typ]()
    if err := json.NewDecoder(r.Body).Decode(obj); err != nil {
        panic(err)
    }

    // At this point obj's type is interface{} but to do anything
    // meaningful with it you'll probably want to know its underlying
    // type. You can get the underlying type with type assertion or
    // using a type switch as demostrated below. 
    switch val := obj.(type) {
    case *Foo:
        // in this block val's type is *Foo
    case *Bar:
        // in this block val's type is *Bar
    case *Baz:
        // in this block val's type is *Baz
    }
}