About this project

# Go REST Client Library This project provides a Go library and command-line tool for executing HTTP requests defined in `.http` files, the format popularized by JetBrains IDEs and the VS Code REST Client extension. It aims for full compatibility with these tools, allowing developers to use the same request files for both manual testing in an IDE and automated end-to-end (E2E) tests in Go. ## Key Features - **JetBrains/VS Code Compatibility**: Parses `.http` files using the same syntax, variables, and behaviors as popular IDE extensions. - **Variable Substitution**: Supports custom variables, environment variables, and system variables like `{{$guid}}`, `{{$randomInt}}`, `{{$timestamp}}`, and `{{$datetime}}`. - **Response Chaining**: Reference responses from other requests in the same file, e.g., `{{authenticate.response.body.token}}`. - **Request Referencing**: Use `@ref` (cached per run) or `@forceRef` (always re-executes) to run prerequisite requests, and `@import` to share named requests across files. - **Request Control**: Skip requests with `@disabled`, pause before sending with `@sleep <ms>`, and loop requests with `@loop`. - **Response Validation**: Compare responses against `.hresp` files with placeholders like `{{$any}}`, `{{$regexp}}`, and `{{$anyGuid}}`. - **Multiple Requests per File**: Separate requests with `###`. - **E2E Testing Ready**: Designed for automated integration tests. ## HTTP File Format `.http` files are plain text files defining HTTP requests. A request consists of an optional name, method, URL, headers, and body. ```http ### Request Name METHOD URL Header1: value1 body content ``` ### Example ```http @baseUrl = https://api.example.com @userId = 123 ### Get user profile GET {{baseUrl}}/users/{{userId}} Authorization: Bearer {{authToken}} X-Request-ID: {{$guid}} ``` ## Library Usage ### Installation ```bash go get github.com/bmcszk/go-restclient ``` ### Execute Requests in Go ```go package main import ( "context" "log" "github.com/bmcszk/go-restclient" ) func main() { client, _ := restclient.NewClient( restclient.WithVars(map[string]interface{}{ "authToken": "your-token-here", }), ) responses, _ := client.ExecuteFile(context.Background(), "requests.http") for i, resp := range responses { if resp.Error != nil { log.Printf("Request %d failed: %v", i+1, resp.Error) } else { log.Printf("Request %d: %d %s", i+1, resp.StatusCode, resp.Status) } } } ``` ### Client Options ```go client, err := restclient.NewClient( restclient.WithBaseURL("https://api.example.com"), restclient.WithDefaultHeader("X-API-Key", "secret"), restclient.WithHTTPClient(customHTTPClient), restclient.WithVars(variables), ) ``` ## CLI Usage The `restclient` CLI runs `.http` files from the command line. ### Installation ```bash go install github.com/bmcszk/go-restclient/cmd/restclient@latest ``` ### Basic Commands ```bash restclient -f requests.http --all restclient -f requests.http -n "get user" restclient -f requests.http -i 0 restclient --version ``` ### List Requests ```bash restclient -f requests.http --list ``` ### Run a Single Request By name (case-insensitive): ```bash restclient -f requests.http -n "create user" ``` By 0-based index: ```bash restclient -f requests.http -i 0 ``` ### Command-Line Variables ```bash restclient -f requests.http -D token=abc123 -D env=prod ``` ### Prerequisite Requests ```bash restclient -f requests.http -n "get protected" -A authenticate ``` ### Fail on Errors Exit with code 1 on HTTP 4xx/5xx responses: ```bash restclient -f requests.http -E ``` ### Output Formats ```bash # Body only restclient -f requests.http -o body # JSON path extraction restclient -f requests.http -o jsonpath "data.users[0].name" # Environment variable format restclient -f requests.http -o env "token" ``` ### CLI Flags | Short | Long | Description | | ----- | ---- | ----------- | | `-f` | `--file` | Request file path (required) | | `-n` | `--name` | Run request by name | | `-i` | `--index` | Run request by index | | | `--all` | Run all requests in file | | `-e` | `--expected` | Expected response file | | | `--e-name` | Expected response name | | | `--e-index` | Expected response index | | `-l` | `--list` | List requests | | `-E` | `--fail-on-error` | Fail on 4xx/5xx | | `-o` | `--output` | Output format | | `-A` | `--after` | Prerequisite request | | `-D` | `--define` | Define variable (repeatable) | ## Response Validation Create `.hresp` files to validate responses. **responses.hresp:** ```http HTTP/1.1 200 OK Content-Type: application/json { "id": "{{$anyGuid}}", "name": "{{$any}}", "createdAt": "{{$anyTimestamp}}" } ``` **Validate in Go:** ```go err := client.ValidateResponses("responses.hresp", responses...) if err != nil { log.Fatal("Validation failed:", err) } ``` ### Validation Placeholders - `{{$any}}` - Matches any text - `{{$regexp ``pattern``}}` - Regex pattern (in backticks) - `{{$anyGuid}}` - UUID format - `{{$anyTimestamp}}` - Unix timestamp - `{{$anyDatetime 'format'}}` - Datetime (rfc1123, iso8601, or custom) ## Use Cases ### Manual Testing Use your favorite IDE extension to test APIs during development. ### Automated E2E Testing ```go func TestUserAPI(t *testing.T) { client, _ := restclient.NewClient( restclient.WithBaseURL(testServer.URL), ) responses, err := client.ExecuteFile(context.Background(), "user_tests.http") require.NoError(t, err) err = client.ValidateResponses("user_expected.hresp", responses...) require.NoError(t, err) } ``` ## Development ### Prerequisites - Go 1.21+ ### Commands ```bash make check # Run all checks (lint, test, build) ``` ## License MIT License