client.tmpl 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Doer performs HTTP requests.
  2. //
  3. // The standard http.Client implements this interface.
  4. type HTTPRequestDoer interface {
  5. Do(req *http.Request) (*http.Response, error)
  6. }
  7. // Client which conforms to the OpenAPI3 specification for this service.
  8. type Client struct {
  9. // The endpoint of the server conforming to this interface, with scheme,
  10. // https://api.deepmap.com for example. This can contain a path relative
  11. // to the server, such as https://api.deepmap.com/dev-test, and all the
  12. // paths in the swagger spec will be appended to the server.
  13. Server string
  14. // Server + /api/v2/
  15. APIEndpoint string
  16. // Doer for performing requests, typically a *http.Client with any
  17. // customized settings, such as certificate chains.
  18. Client HTTPRequestDoer
  19. }
  20. // Creates a new Client, with reasonable defaults
  21. func NewClient(server string, doer HTTPRequestDoer) (*Client, error) {
  22. // create a client with sane default values
  23. client := Client{
  24. Server: server,
  25. Client: doer,
  26. }
  27. // ensure the server URL always has a trailing slash
  28. if !strings.HasSuffix(client.Server, "/") {
  29. client.Server += "/"
  30. }
  31. // API endpoint
  32. client.APIEndpoint = client.Server + "api/v2/"
  33. // create httpClient, if not already present
  34. if client.Client == nil {
  35. client.Client = &http.Client{}
  36. }
  37. return &client, nil
  38. }
  39. func(e *Error) Error() error {
  40. return fmt.Errorf("%s: %s", string(e.Code), *e.Message)
  41. }
  42. func unmarshalJSONResponse(bodyBytes []byte, obj interface{}) error {
  43. if err := json.Unmarshal(bodyBytes, obj); err != nil {
  44. return err
  45. }
  46. return nil
  47. }
  48. func isJSON(rsp *http.Response) bool {
  49. ctype, _, _ := mime.ParseMediaType(rsp.Header.Get("Content-Type"))
  50. return ctype == "application/json"
  51. }
  52. func decodeError(body []byte, rsp *http.Response) error {
  53. if isJSON(rsp) {
  54. var serverError struct {
  55. Error
  56. V1Error *string `json:"error,omitempty"`
  57. }
  58. err := json.Unmarshal(body, &serverError)
  59. if err != nil {
  60. message := fmt.Sprintf("cannot decode error response: %v", err)
  61. serverError.Message = &message
  62. }
  63. if serverError.V1Error != nil {
  64. serverError.Message = serverError.V1Error
  65. serverError.Code = ErrorCodeInvalid
  66. }
  67. if serverError.Message == nil && serverError.Code == "" {
  68. serverError.Message = &rsp.Status
  69. }
  70. return serverError.Error.Error()
  71. } else {
  72. message := rsp.Status
  73. if len(body) > 0 {
  74. message = message + ": " + string(body)
  75. }
  76. return errors.New(message)
  77. }
  78. }