{"id":13741888,"url":"https://github.com/ysyesilyurt/go-restclient","last_synced_at":"2026-03-10T11:34:44.666Z","repository":{"id":48963936,"uuid":"349569122","full_name":"ysyesilyurt/go-restclient","owner":"ysyesilyurt","description":"A Handy Go Package to Call HTTP APIs","archived":false,"fork":false,"pushed_at":"2021-12-26T11:09:08.000Z","size":48,"stargazers_count":10,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-08T22:37:25.430Z","etag":null,"topics":["builder","builder-pattern","client","go","go-restful","golang","httpclient","rest","restclient","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ysyesilyurt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-19T22:21:15.000Z","updated_at":"2023-07-14T12:50:31.000Z","dependencies_parsed_at":"2022-09-21T10:34:24.154Z","dependency_job_id":null,"html_url":"https://github.com/ysyesilyurt/go-restclient","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ysyesilyurt/go-restclient","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysyesilyurt%2Fgo-restclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysyesilyurt%2Fgo-restclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysyesilyurt%2Fgo-restclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysyesilyurt%2Fgo-restclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ysyesilyurt","download_url":"https://codeload.github.com/ysyesilyurt/go-restclient/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ysyesilyurt%2Fgo-restclient/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30332404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builder","builder-pattern","client","go","go-restful","golang","httpclient","rest","restclient","wrapper"],"created_at":"2024-08-03T04:01:03.721Z","updated_at":"2026-03-10T11:34:44.647Z","avatar_url":"https://github.com/ysyesilyurt.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# go-restclient\n\nA Handy Go Package to Call Internal HTTP APIs with Builder Pattern\n\n```\ngo get github.com/ysyesilyurt/go-restclient/restclient\n```\n\n## Write Once, Use Everywhere\n\nEssentially `go-restclient` is a handy `builder` wrapper around `net/http` for all the [_pretty standard\nstuff_](#execution-flow)\nthat needs to be repeated in all HTTP Request/Response cycles. The purpose is to save you from the pain of massive code\nduplication those ordinary cycles may lead.\n\nAs the number of distinct Internal HTTP requests you are making grows, the need for such a wrapper package also\nexponentially grows. In that sense  _handiness_ level of `go-restclient` is directly proportional to your need for such\nrequest/responses 🙂\n\n### Execution Flow\n\nAfter a `Build()` call on `restclient.RequestBuilder()` upon one or many builder method calls:\n\n* Constructs URL by escaping path components using provided components\n* Sets queryParams if exists\n* Validates that resulting URI is valid\n* Sets custom and universal headers\n* Sets authentication strategy to be used\n* Sets Authorization header by applying provided authentication strategy\n* Sets provided RequestBody if exists (or marshals then sets if given as JSON Body)\n* Builds the request object\n* Sets request context timeout and defer its cancellation\n* Does Request (Times and Logs it if needed)\n* Handles Response Status Code and any errors that can be returned from client's call (returns a\n  detailed [`restclient.RequestError`](#error-handling))\n* Reads the body and unmarshal it into given variable's reference\n\n## Usage\n\n* First build your HTTP Request using `restclient.RequestBuilder()` constructor and with all the builder methods you\n  need.\n\n```\n// https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\nreq, reqErr := restclient.RequestBuilder().\n\t\tScheme(\"https\").\n\t\tHost(\"ysyesilyurt.com\").\n\t\tPathElements([]string{\"tasks\", \"1\"}).\n\t\tQueryParams(\u0026queryParams).\n\t\tHeader(\u0026headers).\n\t\tAuth(testAuth).\n\t\tResponseReference(\u0026response).\n\t\tLoggingEnabled(true).\n\t\tTimeout(30 * time.Second).\n\t\tBuild()\nif reqErr != nil {\n\treturn errors.Wrap(reqErr, \"Failed to construct HTTP request\")\n}\n```\n\n* Then make your call...\n\n```\nreqErr = req.Get()\nif reqErr != nil {\n\treturn errors.Wrap(reqErr, \"Failed to perform HTTP GET request\")\n}\n```\n\n### Available HTTP Calls\n\n* `Get() RequestError`\n* `Post() RequestError`\n* `Put() RequestError`\n* `Patch() RequestError`\n* `Delete() RequestError`\n\n### Available Builders\n\n* `Scheme(scheme string)` -\u003e Sets scheme field of your URL. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                Scheme(\"https\").\n                Build()\n```\n\n* `Host(host string)` -\u003e Sets host field of your URL. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                Scheme(\"https\").\n                Host(\"ysyesilyurt.com\").\n                Build()\n```\n\n* `PathElements(pe []string)` -\u003e Sets elements that reside in your URL's Path (not the query params) in the order given\n  in the array. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                Scheme(\"https\").\n                Host(\"ysyesilyurt.com\").\n                PathElements([]string{\"tasks\", \"1\"}).\n                Build()\n```\n\n* `QueryParams(qp *url.Values)` -\u003e Sets the Query Parameters that reside in your URL in the order given in the array.\n  Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                Scheme(\"https\").\n                Host(\"ysyesilyurt.com\").\n                PathElements([]string{\"tasks\", \"1\"}).\n                QueryParams(\u0026url.Values{\"tenantId\": []string{\"d90c3101-53bc-4c54-94db-21582bab8e17\"}, \"vectorId\": []string{\"1\"}}).\n                Build()\n```\n\n* `RawUrl(rawUrl string)` -\u003e Use this one if you do not want to parse your URL into several builder methods above and\n  see your URL as a whole. This one will automatically parse your URL and set the fields accordingly. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Build()\n```\n\n* `Header(header *http.Header)` -\u003e Sets the headers that you want to include in your request. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                Build()\n```\n\n* `Body(body io.Reader)` -\u003e Sets the request body in the form of `io.Reader` for your request, if you want to include a\n  body for your request of course. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                Body(bytes.NewBufferString(query)).\n                Build()\n```\n\n* `BodyJson(bodyJson interface{})` -\u003e Use this one instead of `Body(body io.Reader)` if your request body is in JSON\n  form. You can pass your struct object directly to this builder method, it is going to marshal your object and set the\n  body as `io.Reader`. Example:\n\n```\nrequestBody := dummyBodyDto{\n    Id:   123,\n    Name: \"1234\",\n}\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                BodyJson(requestBody).\n                Build()\n```\n\n* `Auth(auth Authenticator)` -\u003e Sets the Authentication Strategy for your request. Implement `restclient.Authenticator`\n  to create your own `Authenticator`, an example `Basic Auth` implementation can be found in `basic_authenticator.go`.\n  Example:\n\n```\nbasicAuth := newBasicAuthenticator(\"ysyesilyurt\", \"0123\")\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                Auth(basicAuth).\n                Build()\n```\n\n* `ResponseReference(respRef interface{})` -\u003e Sets the reference of the variable to map response object returned from\n  request. Example:\n\n```\nvar response dummyHttpResponse\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                ResponseReference(\u0026response).\n                Build()\n```\n\n* `Request(req *http.Request)` -\u003e If you happen to have a pre-prepared valid `http.Request` object and want to build a\n  new request upon this request then you can simply use this builder method. Example:\n\n```\nvar response dummyHttpResponse\nreq, reqErr := restclient.RequestBuilder().\n                Request(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Header(\u0026http.Header{\"Content-Type\": []string{\"application/json\"}, \"Cookie\": []string{\"test-1234\"}}).\n                ResponseReference(\u0026response).\n                Build()\n```\n\n* `Timeout(timeout time.Duration)` -\u003e Sets the timeout value that should be used for the request. _Default_ is 60\n  seconds. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                Timeout(30 * time.Second)             \n                Build()\n```\n\n* `LoggingEnabled(enabled bool)` -\u003e Decides whether responses should be logged or not. _Default_ is false. Example:\n\n```\nreq, reqErr := restclient.RequestBuilder().\n                RawUrl(\"https://ysyesilyurt.com/tasks/1?tenantId=d90c3101-53bc-4c54-94db-21582bab8e17\u0026vectorId=1\").\n                LoggingEnabled(true)             \n                Build()\n```\n\n## Error Handling\n\n`go-restclient` defines `restclient.RequestError` interface to cover all the errors that can be returned\nfrom `restclient.RequestBuilder.Build()` and result of the HTTP calls. The top level errors returned by the client can\nbe seen\nin [errors.go](https://github.com/ysyesilyurt/go-restclient/blob/bc71e1bf147e9293635583edbca00e5db08dd7d5/restclient/errors.go#L9)\n. The methods that can be used within the boundaries of `restclient.RequestError` are as follows:\n\n```\ntype RequestError interface {\n\tError() string\n\tGetTopLevelError() error   // GetTopLevelError returns top level error that originates the title\n\tGetUnderlyingError() error // GetUnderlyingError returns underlying error that originates the message\n\tGetTitle() string          // GetTitle returns top level error 'title' referring to message\n\tGetMessage() string        // GetMessage returns detailed error message for the request\n\tGetStatusCode() int        // GetStatusCode returns status code for the request. '0' means request failed for some reason and can be checked using methods below\n\tTimeout() bool             // Timeout returns if request failed due to a timeout\n\tConnectionError() bool     // ConnectionError returns if request failed due to a connection error (Failed to get response for some reason)\n\tResponseParseError() bool  // ResponseParseError returns if response of the request could not be parsed into given response reference variable\n\tRequestBuildError() bool   // RequestBuildError returns if request could not be built due to some reason\n}\n```\n\n## Legacy Version\n\nYou can also use the legacy version which is located\non [`legacy` branch](https://github.com/ysyesilyurt/go-restclient/tree/legacy) if you want to use `go-restclient` using\ntraditional ways (with constructing the helper objects and using those altogether blah blah...) or if you want to use a\nversion that allows reusing the HTTP clients that's being used internally for sending the requests (Thanks to separation\nof these objects, this legacy version of `go-restclient` gives you the slightly extended feature set like _separation of\nclient timeouts and request-specific timeouts_ and etc.). You can find more information about the version itself and its\nusage from [here](https://github.com/ysyesilyurt/go-restclient/tree/legacy#go-restclient-legacy-version). But all in all, I think the builder version is more handy and elegant so I just wanted to keep\nbuilder version on the master branch.\n\n## Contribution\n\nUnit tests are implemented for the codebase but all the edge cases might not be covered, weird bugs may appear in such\ncases. Feel free to open an issue if you spot a bug. In addition if you have an improvement idea you can request it in\nthe form of an issue (with providing a clear and brief description of the feature) or you can develop the improvement\nand open a PR with again a brief description of the reasoning.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fysyesilyurt%2Fgo-restclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fysyesilyurt%2Fgo-restclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fysyesilyurt%2Fgo-restclient/lists"}