Custom Code With SDK Hooks

Info Icon

Availability

SDK Hooks are only available for Enterprise users.

The Speakeasy SDK Hooks feature allows users to add custom logic to SDK functions and request lifecycles across supported SDKs. Use hooks to insert code into events and enable functionality like transformations, tracing, logging, validation, and error handling.

SDK Hooks can be used in the following lifecycle events:

  • On SDK initialization: Modify the base server URL, wrap or override the HTTP client, add tracing, inject global headers, and manage authentication.
  • Before request: Cancel an outgoing request, transform the request contents, or add tracing.
  • After success: When a successful response is received, add tracing and logging, validate the response, return an error, or transform the raw response before deserialization.
  • After error: On connection errors or unsuccessful responses, add tracing and logging or transform the returned error.

Adding a Hook

Supported SDKs created with the most recent version of the Speakeasy CLI will include a hooks directory for generated code.

LanguageDirectory Path
Gointernal/hooks
Pythonsrc/{sdk_name}/hooks
Python (v2)src/{sdk_name}/_hooks
TypeScriptsrc/hooks
Javasrc/main/java/{package_path}/hooks
C#{root_path}/Hooks

Steps to Add a Hook

  1. Create a hook implementation.

Develop your hook implementation in a new file in the hooks directory.

Files you add to the SDK repo won't be overridden by the generator.

  1. Locate the registration file.
LanguageRegistration File Path
Gointernal/hooks/registration.go
Pythonsrc/{sdk_name}/hooks/registration.py
Python(v2)src/{sdk_name}/_hooks/registration.py
TypeScriptsrc/hooks/registration.ts
Javasrc/main/java/{package_path}/hooks/SDKHooks.java
C#{root_path}/Hooks/HookRegistration.cs
  1. Instantiate and register your hook.

In the registration file, find the initHooks/init_hooks/initialize/InitHooks method. This method includes a hooks parameter that allows the registration of hooks for different lifecycle events.

Instantiate your hook in this method (it is called once per SDK instantiation) and register it for each event that triggers it.


package hooks
func initHooks(h *Hooks) {
myHook := &ExampleHook{}
h.registerBeforeRequestHook(myHook)
}

Info Icon

Note

The registration file is generated once and will not be overwritten. After the initial generation, you have full control and ownership of it.

Here are some example hooks for each of the four events.


package hooks
import (
"net/http"
)
type ExampleHook struct{}
var (
_ sdkInitHook = (*ExampleHook)(nil)
_ beforeRequestHook = (*ExampleHook)(nil)
_ afterSuccessHook = (*ExampleHook)(nil)
_ afterErrorHook = (*ExampleHook)(nil)
)
func (i *ExampleHook) SDKInit(baseURL string, client HTTPClient) (string, HTTPClient) {
// modify the baseURL or wrap the client used by the SDK here and return the updated values
return baseURL, client
}
func (i *ExampleHook) BeforeRequest(hookCtx BeforeRequestContext, req *http.Request) (*http.Request, error) {
// modify the request object before it is sent, such as adding headers or query parameters, or return an error to stop the request from being sent
return req, nil
}
func (i *ExampleHook) AfterSuccess(hookCtx AfterSuccessContext, res *http.Response) (*http.Response, error) {
// modify the response object before deserialization or return an error to stop the response from being deserialized
return res, nil
}
func (i *ExampleHook) AfterError(hookCtx AfterErrorContext, res *http.Response, err error) (*http.Response, error) {
// modify the response before it is deserialized as a custom error or the error object before it is returned or return an error wrapped in the FailEarly error in this package to exit from the hook chain early
return res, err
}

Adding Dependencies

If you need to add new external or third-party dependencies to the SDK to power logic in SDK hooks, configure additionalDependencies in the gen.yaml file according to the language-specific instructions below. These dependencies are templated into the SDK and pulled on compilation.

Pass a map of Go package names to the version to be added to the go.mod file of the SDK.


configVersion: 2.0.0
go:
additionalDependencies:
"github.com/google/uuid": v1.6.0