diff --git a/README.md b/README.md index 4f23789..ce27082 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,23 @@ -# JSON specified HTTP client +# JSON-specialized HTTP client [![PkgGoDev](https://pkg.go.dev/badge/github.com/koron-go/jsonhttpc)](https://pkg.go.dev/github.com/koron-go/jsonhttpc) [![Actions/Go](https://github.com/koron-go/jsonhttpc/workflows/Go/badge.svg)](https://github.com/koron-go/jsonhttpc/actions?query=workflow%3AGo) [![Go Report Card](https://goreportcard.com/badge/github.com/koron-go/jsonhttpc)](https://goreportcard.com/report/github.com/koron-go/jsonhttpc) -Package jsonhttpc provides JSON specialized HTTP Client. +Package jsonhttpc provides a way to easily send and receive HTTP requests with JSON bodies. -* request and response is encoded/decoded as JSON automatically. -* bit convenient for repeating requests. +* Request and response is encoded/decoded as JSON automatically. +* Bit handy for repeating requests. * specify base URL - `WithBaseURL()` * specify HTTP Client - `WithClient()` * specify HTTP header - `WithHeader()` -* tips to customize requests - `Do()` +* Tips to customize requests - for `Do()` * `ContentType() string` on `body` overrides "Content-Type" header. (default is "application/json") -* error response is decoded as JSON - `Error` +* Responses are automatically JSON-decoded even in case of errors - `Error` * Most of JSON properties are put into `Properties map[string]interface{}` - * There are some fields for - [RFC7808 Problem Details for HTTP APIs][rfc7808] + * Error responses that follow [RFC7808 Problem Details for HTTP APIs][rfc7808] are a bit easier to handle. (Japanese) @@ -27,13 +26,19 @@ Package jsonhttpc provides JSON specialized HTTP Client. * ベースURLを設定できる `WithBaseURL()` * HTTP Clientを設定できる `WithClient()` * ヘッダーを設定できる `WithHeader()` -* リクエストをカスタマイズするtipsがあります `Do()` +* リクエストをカスタマイズするtipsがあります - for `Do()` * `body` に `ContentType() string` を実装するとContent-Typeヘッダーを変更 できます (デフォルトは `application/json`) * エラーの際もレスポンスは自動的にJSONデコードされます * `Error.Properties` に `map[string]interface{}` で入ります * [RFC7808 Problem Details for HTTP APIs][rfc7808] は少し楽できます -## How to use - [rfc7808]:https://tools.ietf.org/html/rfc7807 + +## Install and update + +```console +$ go get github.com/koron-go/jsonhttpc@latest +``` + +## How to use diff --git a/client.go b/client.go index d827f6e..03ee81c 100644 --- a/client.go +++ b/client.go @@ -24,6 +24,8 @@ type Client struct { } // New creates a new Client with base URL. +// You can pass nil to baseURL, in which case you should pass a complete URL to +// the pathOrURL argument of Do() function. func New(baseURL *url.URL) *Client { return &Client{ u: baseURL, @@ -66,13 +68,6 @@ func (c *Client) WithHeader(h http.Header) *Client { // This returns an error when `pathOrURL` starts with "jsonhttpc.Parse error: " // to treat `Path()`'s failure as error. func (c *Client) Do(ctx context.Context, method, pathOrURL string, body, receiver interface{}) error { - if strings.HasPrefix(pathOrURL, "jsonhttpc.Parse error: ") { - return errors.New(pathOrURL) - } - if ctx == nil { - ctx = context.Background() - } - // prepare the request. req, err := c.newRawRequest(ctx, method, pathOrURL, body) if err != nil { @@ -134,6 +129,9 @@ func (c *Client) newRawRequest(ctx context.Context, method, pathOrURL string, bo } func (c *Client) parseURL(pathOrURL string) (*url.URL, error) { + if strings.HasPrefix(pathOrURL, "jsonhttpc.Parse error: ") { + return nil, errors.New(pathOrURL) + } if c.u != nil { return c.u.Parse(pathOrURL) } diff --git a/error.go b/error.go index 7ee2dd6..a76f411 100644 --- a/error.go +++ b/error.go @@ -111,6 +111,7 @@ func parseError(r *http.Response) (*Error, error) { return er, nil } +// Error returns error message. func (er *Error) Error() string { return fmt.Sprintf("error: status=%q props=%#v", er.Status, er.Properties) }