Batch multiple requests
Combine several REST requests into a single HTTP call and read back the per-request results.
When to use this pattern
- You're making several independent requests in one logical operation (for example, creating an incident and updating a user) and want them to travel in a single round-trip
- You're reducing latency for many small operations
- If you're fetching many pages of one collection, use Pagination instead; if the requests depend on each other's results, send them sequentially
Required values
| Value | Description |
|---|---|
| The requests | Built with any builder's ToXRequestInformation method, unsent |
Example
The example uses a small helper, batchRequests, that wraps
RequestInformation objects into a BatchRequestModel:
package main
import (
"context"
"fmt"
"log"
servicenow "github.com/michaeldcanady/servicenow-sdk-go/v2"
"github.com/michaeldcanady/servicenow-sdk-go/v2/credentials"
abstractions "github.com/microsoft/kiota-abstractions-go"
)
// batchRequests A helper function to combine provided request information into a single `BatchRequest`.
func batchRequests(excludeResponseHeaders bool, requests ...*abstractions.RequestInformation) (*batchapi.BatchRequestModel, error) {
body := batchapi.NewBatchRequestModel()
for _, request := range requests {
restRequest, err := batchapi.CreateRestRequestFromRequestInformation(request, excludeResponseHeaders)
if err != nil {
return nil, err
}
if err := body.AddRequest(restRequest); err != nil {
return nil, err
}
}
return body, nil
}
func main() {
// Step 1: Authenticate and initialize the client
cred := credentials.NewBasicProvider("{username}", "{password}")
client, err := servicenow.NewServiceNowServiceClient(
servicenow.WithAuthenticationProvider(cred),
servicenow.WithInstance("{instance}"),
)
if err != nil {
log.Fatalf("failed to initialize client: %v", err)
}
ctx := context.Background()
// Step 2: Describe the requests to combine — ToXRequestInformation
// builds a request without sending it
var requests []*abstractions.RequestInformation
incidents, err := client.Now().Table("incident").ToGetRequestInformation(ctx, nil)
if err != nil {
log.Fatal(err)
}
users, err := client.Now().Table("sys_user").ToGetRequestInformation(ctx, nil)
if err != nil {
log.Fatal(err)
}
requests = append(requests, incidents, users)
// Step 3: Combine them into one batch body
body, err := batchRequests(true, requests...)
if err != nil {
log.Fatal(err)
}
// Step 4: Send the batch in a single HTTP call
response, err := client.Now().Batch().Post(ctx, body, nil)
if err != nil {
log.Fatalf("batch request failed: %v", err)
}
// Step 5: Inspect the per-request results
serviced, err := response.GetServicedRequests()
if err != nil {
log.Fatal(err)
}
unserviced, err := response.GetUnservicedRequests()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d requests serviced, %d unserviced\n", len(serviced), len(unserviced))
}
Tips
- ServiceNow executes the sub-requests independently — a batch isn't a
transaction. Check
GetUnservicedRequests()for the ones that didn't run. - Each serviced request carries its own status code and body; a
200on the batch only means the batch itself was processed. - Any API's requests can be mixed in one batch: table, attachment, and the rest.
Next steps
- Table operations: The requests you'll batch most often.
- Batch API reference: All parameters, in both modalities.