Implement JSON-RPC client foundation
Add core JSON-RPC 2.0 protocol implementation for Kanboard API: - JSONRPCRequest/Response/Error structs with proper JSON tags - Generic call() method for sending requests and parsing responses - Thread-safe request ID generation using atomic.Int64 - Automatic /jsonrpc.php path appending to baseURL - Support for subdirectory installations - HTTP Basic Auth support (API token and username/password) - Error handling for unauthorized/forbidden responses Includes comprehensive tests with httptest mock server. Closes: kanboard-api-2g1
This commit is contained in:
parent
347fb75f11
commit
a486a73ce1
6 changed files with 611 additions and 1 deletions
47
client.go
Normal file
47
client.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package kanboard
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Client is the Kanboard API client.
|
||||
type Client struct {
|
||||
baseURL string
|
||||
endpoint string
|
||||
httpClient *http.Client
|
||||
auth Authenticator
|
||||
}
|
||||
|
||||
// NewClient creates a new Kanboard API client.
|
||||
// The baseURL should be the base URL of the Kanboard instance (e.g., "https://kanboard.example.com").
|
||||
// The path /jsonrpc.php is appended automatically.
|
||||
// Supports subdirectory installations (e.g., "https://example.com/kanboard" → POST https://example.com/kanboard/jsonrpc.php).
|
||||
func NewClient(baseURL string) *Client {
|
||||
// Ensure no trailing slash
|
||||
baseURL = strings.TrimSuffix(baseURL, "/")
|
||||
|
||||
return &Client{
|
||||
baseURL: baseURL,
|
||||
endpoint: baseURL + "/jsonrpc.php",
|
||||
httpClient: http.DefaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
// WithAPIToken configures the client to use API token authentication.
|
||||
func (c *Client) WithAPIToken(token string) *Client {
|
||||
c.auth = &apiTokenAuth{token: token}
|
||||
return c
|
||||
}
|
||||
|
||||
// WithBasicAuth configures the client to use username/password authentication.
|
||||
func (c *Client) WithBasicAuth(username, password string) *Client {
|
||||
c.auth = &basicAuth{username: username, password: password}
|
||||
return c
|
||||
}
|
||||
|
||||
// WithHTTPClient sets a custom HTTP client.
|
||||
func (c *Client) WithHTTPClient(client *http.Client) *Client {
|
||||
c.httpClient = client
|
||||
return c
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue