code: func NewRequestJSON(ctx context.Context, c *http.Client, rFn retry.Factory, url, method string, headers map[string]string, in, out interface{}) (func() (int, error), error) {
  	var encoded []byte
  	if in != nil {
  		var err error
  		if encoded, err = json.Marshal(in); err != nil {
  			return nil, err
  		}
  	}
  
  	return NewRequest(ctx, c, rFn, func() (*http.Request, error) {
  		var body io.Reader
  		if encoded != nil {
  			body = bytes.NewReader(encoded)
  		}
  
  		req, err := http.NewRequest(method, url, body)
  		if err != nil {
  			return nil, err
  		}
  		if encoded != nil {
  			req.Header.Set("Content-Type", jsonContentTypeForPOST)
  		}
  		if headers != nil {
  			for k, v := range headers {
  				req.Header.Add(k, v)
  			}
  		}
  		return req, nil
  	}, func(resp *http.Response) error {
  		defer resp.Body.Close()
  		if ct := strings.ToLower(resp.Header.Get("Content-Type")); !strings.HasPrefix(ct, jsonContentType) {
  			// Non-retriable.
  			return fmt.Errorf("unexpected Content-Type, expected \"%s\", got \"%s\"", jsonContentType, ct)
  		}
  		if out == nil {
  			// The client doesn't care about the response. Still ensure the response
  			// is valid json.
  			out = &map[string]interface{}{}
  		}
  		if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
  			// Retriable.
  			return errors.Annotate(err, "bad response %s", url).Tag(transient.Tag).Err()
  		}
  		return nil
  	}, nil), nil
  }
docs: // NewRequestJSON returns a retriable request calling a JSON endpoint.