Configure the client
Compose a client from functional options: target instance, HTTP pipeline, transport, and logging.
When to use this pattern
- You're going beyond the two-option default (
WithAuthenticationProvider+WithInstance) — adding middleware, timeouts, or logging - You need request/response visibility for debugging or metrics
- You're running behind a proxy or with custom TLS and need transport control
Required values
| Value | Description |
|---|---|
| Instance or URL | WithInstance("{instance}"), or WithURL(...) for a full base URL (for example, behind a proxy) |
| Credentials | Any provider from the Authentication guide |
Example
A client with the default pipeline plus a logging middleware, a 30-second transport timeout, and an SDK diagnostics logger:
package main
import (
"log"
"net/http"
"time"
servicenowsdkgo "github.com/michaeldcanady/servicenow-sdk-go/v2"
"github.com/michaeldcanady/servicenow-sdk-go/v2/credentials"
nethttplibrary "github.com/microsoft/kiota-http-go"
)
type myLoggingMiddleware struct{}
func (m *myLoggingMiddleware) Intercept(
pipeline nethttplibrary.Pipeline, middlewareIndex int, req *http.Request,
) (*http.Response, error) {
start := time.Now()
resp, err := pipeline.Next(req, middlewareIndex)
log.Printf("%s %s -> %v (%s)", req.Method, req.URL.Path, err, time.Since(start))
return resp, err
}
type stdLogger struct{}
func (stdLogger) Log(message string, args ...interface{}) {
log.Printf(message, args...)
}
func main() {
// Step 1: Credentials (see the Authentication guide for OAuth2 flows)
cred := credentials.NewBasicProvider("{username}", "{password}")
// Step 2: Extend the default middleware chain — keep the built-in
// retries, redirects, and compression, and add your own handler
middleware := append(
nethttplibrary.GetDefaultMiddlewares(),
&myLoggingMiddleware{},
)
// Step 3: Compose the client from options
client, err := servicenowsdkgo.NewServiceNowServiceClient(
servicenowsdkgo.WithAuthenticationProvider(cred),
servicenowsdkgo.WithInstance("{instance}"),
servicenowsdkgo.WithMiddleware(middleware...),
servicenowsdkgo.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
servicenowsdkgo.WithLogger(stdLogger{}),
)
if err != nil {
log.Fatalf("failed to initialize client: %v", err)
}
// The configured client is what every request builder hangs off
_ = client
}
Variations
Instance vs. URL
servicenowsdkgo.WithInstance("{instance}")
// or, for a full URL (e.g. behind a proxy):
servicenowsdkgo.WithURL("https://{instance}.service-now.com")
Middleware only
middleware := append(
nethttplibrary.GetDefaultMiddlewares(), // keep retries, redirects, compression
&myLoggingMiddleware{},
)
client, err := servicenowsdkgo.NewServiceNowServiceClient(
servicenowsdkgo.WithAuthenticationProvider(cred),
servicenowsdkgo.WithInstance("{instance}"),
servicenowsdkgo.WithMiddleware(middleware...),
)
Supplying WithMiddleware replaces the default chain rather than
appending to it. If you still want retries, redirects, and compression,
start from nethttplibrary.GetDefaultMiddlewares() and append your own
handlers, as shown above.
Transport only
To control transport-level settings (timeouts, TLS, proxies), supply your own
*http.Client:
servicenowsdkgo.WithHTTPClient(&http.Client{Timeout: 30 * time.Second})
Custom logger
Route the SDK's diagnostic output through your own logger — anything with a
Log(message string, args ...interface{}) method:
type stdLogger struct{}
func (stdLogger) Log(message string, args ...interface{}) {
log.Printf(message, args...)
}
servicenowsdkgo.WithLogger(stdLogger{})
When a logger is configured, the SDK's default HTTP pipeline emits one line per request and one per response — retries and redirect hops included:
DEBUG— the outgoing request: method, URL, and attempt number.INFO— responses with a status below 400.WARN— responses with a 4xx or 5xx status.ERROR— requests that failed at the transport level.
Only the method, URL, status code, duration, and attempt number are logged.
Headers (including Authorization and cookies), bodies, URL query strings,
fragments, and userinfo are never logged.
Advanced options
WithRequestAdapter— supply a fully custom Kiotaabstractions.RequestAdapter, taking over serialization and transport entirely. The other pipeline options are ignored when you provide one.WithBackingStoreFactory— replace the backing store implementation used by models, for example to add change tracking.
Tips
- Out of the box the client already retries transient failures with backoff
(including 429s honoring
Retry-After), follows redirects, and handles compression — you don't need any options for that. WithLoggercovers the common request/response diagnostics (see above). Reach for a custom middleware only when you need more detail, such as headers or timing per pipeline stage.- A middleware is any type implementing
Intercept(pipeline, index, req); the example'smyLoggingMiddlewareis the minimal shape.
Next steps
- Authentication: Credential flow options.
- Handling errors: What comes back when a request fails, retries included.