如何在Go语言应用程序中使用usecase指定三种不同类型的响应

x8diyxa7  于 2023-02-10  发布在  Go
关注(0)|答案(1)|浏览(97)

我正在用usecase.Interactor编写一个Go语言的web服务来自动生成OpenAPI3标准的文档,如何正确地发出一个usecase.NewInteractor,使得输出可以是不同的类型?
例如,我的OpenAPI模式描述了三种不同类型的响应:

...
"/phonenumber/get/" : {
  "post" : {
    "operationId" : "getInfo",
    "requestBody" : {
      "required" : true,
      "content" : {
        "application/json" : {
          "schema" : {
            "$ref" : "#/components/schemas/RequestInfo"
          }
        }
      }
    },
    "responses" : {
      "200" : {
        "content" : {
          "application/json" : {
            "schema" : {
              "oneOf" : [ {
                "$ref" : "#/components/schemas/ResponsePhoneExist"
              }, {
                "$ref" : "#/components/schemas/ResponsePhoneNoExist"
              }, {
                "$ref" : "#/components/schemas/ResponsePhoneInArchive"
              } ]
            }
          }
        }
      },
...

ResponsePhoneExistResponsePhoneNoExistResponsePhoneInArchive在我的Go应用中是不同的类型:

type ResponsePhoneExist struct {
  Result string `json:"result,omitempty" required:"true" enum:"ok" example:"ok"`
  Info string `json:"info,omitempty" required:"true" enum:"exist" example:"exist"`
  Phonenumber string `json:"phonenumber,omitempty" required:"true" minLength:"11" maxLength:"11" example:"79146764408"`
  Сount int `json:"count,omitempty" required:"true" minimum:"0" maximum:"3" example:"1"`
  Activated string `json:"activated,omitempty" required:"true" example:"27.11.2022"`
}

type ResponsePhoneNoExist struct {
  Result string `json:"result,omitempty" required:"true" enum:"ok" example:"ok"`
  Info string `json:"info,omitempty" required:"true" enum:"no exist" example:"no exist"`
  Phonenumber string `json:"phonenumber,omitempty" required:"true" minLength:"11" maxLength:"11" example:"79146764408"`
}

type ResponsePhoneInArchive struct {
  Result string `json:"result,omitempty" required:"true" enum:"ok" example:"ok"`
  Info string `json:"info,omitempty" required:"true" enum:"archive" example:"archive"`
  Phonenumber string `json:"phonenumber,omitempty" required:"true" minLength:"11" maxLength:"11" example:"79146764408"`
}

然后,我在main()函数中定义Web服务:

func main() {
  service := web.DefaultService()
  ...
  service.Docs("/docs", v4emb.New)
  service.Post("/phonenumber/get", getPhoneInfo())
  err := http.ListenAndServe(":3400", service)
  ...
}

func getPhoneInfo() usecase.Interactor {
  u := usecase.NewInteractor(func(ctx context.Context, request RequestInfo, response ???) error {
    *response, err = getInfoIn1C(request.PhoneNumber)
    if err != nil {
      return status.Wrap(errors.New(err.Error()), status.Internal)
    }
    return nil
  })
  u.SetName("getInfo")
  u.SetExpectedErrors(status.Unauthenticated, status.InvalidArgument, status.Internal)
  return u
}

func getInfoIn1C(tel string) (???, error) {
  var out ???
  var err error
  ...
  return out, err
}

我应该指定什么类型而不是???,以使自动生成的OpenAPI文档满足上面给出的片段?
我尝试添加此接口:

type ResponsePhone interface {
  ResponsePhoneExist | ResponsePhoneNoExist | ResponsePhoneInArchive
}

但是Go语言返回了一个错误:
不能在类型约束之外使用类型ResponsePhone:接口包含类型约束
我试着修改界面:

type ResponsePhoneConstraint interface {
  ResponsePhoneExist | ResponsePhoneNoExist | ResponsePhoneInArchive
}

type ResponsePhone[T ResponsePhoneConstraint] struct {
  Response T
}

返回这个错误:
无法使用未示例化的泛型类型ResponsePhone[T ResponsePhoneConstraint]。

vq8itlhq

vq8itlhq1#

您应该使用类继承,如下所示:

type ResponsePhoneNoExist struct {
    Result      string `json:"result,omitempty" required:"true" enum:"ok" example:"ok"`
    Info        string `json:"info,omitempty" required:"true" enum:"exist" example:"exist"`
    Phonenumber string `json:"phonenumber,omitempty" required:"true" minLength:"11" maxLength:"11" example:"79146764408"`
}

type ResponsePhoneExist struct {
    ResponsePhoneNoExist
    Сount     int    `json:"count,omitempty" required:"true" minimum:"0" maximum:"3" example:"1"`
    Activated string `json:"activated,omitempty" required:"true" example:"27.11.2022"`
}

type ResponsePhoneInArchive struct {
    ResponsePhoneNoExist
}

1.您可以使用接口{},下面是一个示例:

func getInfoIn1C(tel string) (interface{}, error) {
    out := ResponsePhoneExist{}
    out.Phonenumber = tel
    return &out, nil
}

func getPhoneInfo() {
    response, _ := getInfoIn1C("112233")
    fmt.Printf("%v\n", response)

}

1.您可以使用Generics,下面是一个示例:

func getPhoneInfo() {
    response, _ := getInfoIn1C("112233")
    fmt.Printf("%v\n", response)

}

func getInfoIn1C(tel string) (any, error) {
    out := ResponsePhoneExist{}
    out.Phonenumber = tel
    return any(out), nil
}

ps:type any = interface{} 1与2相同

相关问题