apache/openwhisk-runtime-go

Failing to write a response containing headers

DonRichie opened this issue · 2 comments

Hello,

I am currently trying to create a response containing headers in openwhisk with golang.
I feel like I need a nested map with different value types. But since golang is strongly-typed that is impossible.
I tried to marshal a struct, but failed since the Main functions wants a map as return value.

My best try as response is:

  outobj := make(map[string]interface{})
  outobj["headers"] = "{\"Content-Type\": \"text/html\"}"
  outobj["statusCode"] = 201
  outobj["body"] = "123"
  return outobj

But invoking that action gives an http error.
The reason for that error is the content of the "headers" key. Uncommenting it makes the action work.

Can someone provide an example how to set headers in the golang response?

Here is my best try using a struct, but it fails due to the wrong function signature:

package main

import (
  "fmt"
  "encoding/json"
)

type WhiskResponse struct {
  body string
  statusCode int
  headers map[string]interface{}
}

func PrettyPrint(v interface{}) (err error) {
      b, err := json.MarshalIndent(v, "", "  ")
      if err == nil {
              fmt.Println(string(b))
      }
      return
}

func Main(inobj map[string]interface{}) map[string]interface{} {
  fmt.Println("inobj:")
  PrettyPrint(inobj)
  
  // assemble response
  resp := WhiskResponse{}
  resp.headers["Content-Type"] = "text/html"
  resp.statusCode = 201
  resp.body = "123"
  fmt.Println("resp:")
  PrettyPrint(resp)
  res, err := json.Marshal(resp)
  if err != nil {
    fmt.Println(err)
  }
  return string(res)
}

error:

./exec__.go:37:16: cannot use string(res) (type string) as type map[string]interface {} in return argument

error if changing function signature to "func Main(inobj map[string]interface{}) string {":

./main__.go:56:9: cannot use Main (type func(map[string]interface {}) string) as type Action in assignment

I actually managed to set a header:

package main

import (
  "fmt"
  "encoding/json"
)

func PrettyPrint(v interface{}) (err error) {
      b, err := json.MarshalIndent(v, "", "  ")
      if err == nil {
              fmt.Println(string(b))
      }
      return
}

func Main(inobj map[string]interface{}) map[string]interface{} {
  fmt.Println("inobj:")
  PrettyPrint(inobj)
  
  // assemble response
  outobj := make(map[string]interface{})
  header_map := make(map[string]string)
  header_map["headername"]= "headerval"
  outobj["headers"] = header_map
  outobj["statusCode"] = 201
  outobj["body"] = "123"
  fmt.Println("outobj:")
  PrettyPrint(outobj)
  return outobj
}

I hereby request to extend the documentation with a nice example.