requests.go raw

   1  package clientservices
   2  
   3  import (
   4  	"encoding/json"
   5  	"errors"
   6  	"io"
   7  	"net/http"
   8  
   9  	"github.com/gophercloud/gophercloud"
  10  )
  11  
  12  type RequestService struct {
  13  	serviceClient *gophercloud.ServiceClient
  14  }
  15  
  16  type RequestOptions struct {
  17  	JSONBody interface{}
  18  	OkCodes  []int
  19  }
  20  
  21  func NewRequestService(serviceClient *gophercloud.ServiceClient) *RequestService {
  22  	return &RequestService{serviceClient: serviceClient}
  23  }
  24  
  25  func (s *RequestService) Do(method, url string, options *RequestOptions) (*ResponseResult, error) {
  26  	requestOpts := gophercloud.RequestOpts{
  27  		OkCodes:          options.OkCodes,
  28  		JSONBody:         options.JSONBody,
  29  		KeepResponseBody: true,
  30  	}
  31  
  32  	response, err := s.serviceClient.Request(method, url, &requestOpts)
  33  	if err != nil && !errors.As(err, &gophercloud.ErrUnexpectedResponseCode{}) {
  34  		return nil, err
  35  	}
  36  
  37  	responseResult := &ResponseResult{response, err}
  38  
  39  	return responseResult, nil
  40  }
  41  
  42  // ---------------------------------------------------------------------------------------------------------------------
  43  
  44  // ResponseResult represents a result of a HTTP request.
  45  // It embedded standard http.Response and adds a custom error description.
  46  type ResponseResult struct {
  47  	*http.Response
  48  
  49  	// Err contains error that can be provided to a caller.
  50  	Err error
  51  }
  52  
  53  // ExtractResult allows to provide an object into which ResponseResult body will be extracted.
  54  func (result *ResponseResult) ExtractResult(to interface{}) error {
  55  	body, err := io.ReadAll(result.Body)
  56  	defer result.Body.Close()
  57  	if err != nil {
  58  		return err
  59  	}
  60  
  61  	err = json.Unmarshal(body, to)
  62  	return err
  63  }
  64