Categorygithub.com/jet/go-interstellar
modulepackage
0.0.2
Repository: https://github.com/jet/go-interstellar.git
Documentation: pkg.go.dev

# README

Interstellar - A CosmosDB Client for Go

This library provides a Go client for interacting with the REST/SQL API of CosmosDB. It aims to provide both low-level and high-level API functions.

Interstellar does not work with the other storage APIs such as MongoDB, Cassandra; as those are meant to be used with their respective clients.

Getting Strated

Create a Client using NewClient

An interstellar.Client can be constructed via interstellar.NewClient. This requires at minimum, an interstellar.ConnectionString. A ConnectionString can be parsed from the Azure Connection String using interstellar.ParseConnectionString.

// error handling omitted for brevity

// connection string for Azure CosmosDB Storage Emulator using the well-known AccountKey
cstring   := "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
cs, _     := interstellar.ParseConnectionString(cstring)
client, _ := interstellar.NewClient(cs, nil)

Note: You should not hard-code your connction string in your application; use an environment variable or some form of safe secret injection like HashiCorp Vault.

Optionally, NewClient takes a type that implements interstellar.Requester. You may supply a http.Client here, since this satisifed interface. If a Requester isn't provided, an HTTP Client will be created for this client automatically. Note: http.DefaultClient will NOT be used by default.

This constructor method also adds some retry logic specifically for CosmosDB RetryAfter responses: which will back off and try again when the request rate is too high.

Create a Client Manually

If you want full control over how the client is constructed, you can do this directly by creating an intersteller.Client value.


// well-known AccountKey for Azure CosmosDB Storage Emulator
key, _ := interstellar.ParseMasterKey("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==")
client := &interstellar.Client{
  UserAgent:  interstellar.DefaultUserAgent,
  Endpoint:   "https://localhost:8081",
  Authorizer: key,
  Requester:  http.DefaultClient,
}

Note: In this case, the retry/backoff logic will not be applied.

Examples

List Resources

Uses the List API and automatically paginates unless it is told to stop. There are a few different functions but they all essentially do the same thing.

List Collections Example
var colls []CollectionResource
err := client.WithDatabase("db1").ListCollections(ctx, nil, func(resList []CollectionResource, meta ResponseMetadata) (bool, error) {
    // Add page to slice
    colls = append(colls, resList...)

    // Get next page
    return true, nil
})
Query Documents Example
// error handling omitted for brevity

// Construct a query which returns documents which have a name prefixed with `ab`, 10 per page.
query := &interstellar.Query{
  Query: "SELECT * FROM Documents d WHERE STARTSWITH(d.name,@prefix)",
  Parameters: []interstellar.QueryParameter{
    interstellar.QueryParameter{Name: "@prefix", Value: "ab"},
  },
  MaxItemCount: 10,
}

// Results
var docs []Document

// Perform the query, and paginate through all the results
client.WithDatabase("db1").WithCollection("col1").QueryDocumentsRaw(context.Background(), query, func(resList []json.RawMessage, meta interstellar.ResponseMetadata) (bool, error) {
  for _, raw := range resList {
    var doc Document
    if err := json.Unmarshal(raw, &doc); err != nil {
      return false, err
    }
    docs = append(docs, doc)
  }

  // true = get next page
  return true, nil
})

Note: It is best practice to use parameterized queries like above, especially if your parameter may be from an untrusted/user-suplied source. However, this library cannot detect injection, and cannot stop you from using string concatenation to construct your query.

Running Integration Tests

Running the integration test suite requires a CosmosDB account on Azure or running the CosmosDB Storage emulator.

  1. Create an empty CosmosDB account for testing or run the Storage Emulator.

  2. Set the following environment variables:

    # Set to your connection string (Emulator Account or Read-Write Key)
    # Example given is for the Storage Emulator
    export AZURE_COSMOS_DB_CONNECTION_STRING='AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=='
    # Enable running integration tests
    export RUN_INTEGRATION_TESTS=Y
    # Set to Y If you want very verbose debug logging, with all of the requests and responses
    export DEBUG_LOGGING=Y
    
  3. Run the tests: go test -v .

# Functions

GetResponseMetadata extracts response metadata from the http headers And parses them into native types where applicable (such as time or numbers).
NewClient creates client to the given CoasmosDB account in the ConnectionString And will use the Requester to send HTTP requests and read responses .
ParseArrayFromResponse parses a list of results from the response object mapped by given key.
ParseArrayResponse parses the response into a JSON array Example Input JSON: [1,2,"3",true] .
ParseConnectionString parses a connection string to the storage account The format of the connection string is as follows: AccountEndpoint=https://accountname.documents.azure.com:443/;AccountKey=BASE64KEY; .
ParseMasterKey parses a base-64 encoded shared access key.
ParseObjectResponse parses the response into a json object An error will be returend if the read bytes do not parse to an object with string keys Example Input JSON: { "key1": [1,2,"3",true], "key2": "foo", "key3": { "bar": "baz" } } .

# Constants

APIVersion is the version of the CosmosDB REST API supported See https://docs.microsoft.com/en-us/rest/api/cosmos-db/#supported-rest-api-versions for available versions and changelog.
ConsistencyBounded denotes a slightly weaker consistency than strong.
ConsistencyEventual is the weakest consistency level.
ConsistencySession is consistency scoped to a single client/session.
ConsistencyStrong denotes the operation should be strongly consistent.
ContentTypeJSON is the MIME-Type for generic JSON content.
ContentTypeQueryJSON is the MIME-Type for CosmosDB Queries (json).
DataTypeLineString a GeoJSON LineString.
DataTypeNumber denotes a number type (int or float).
DataTypePoint denotes a GeoJSON Point.
DataTypePolygon denotes a GeoJSON Polygon.
DataTypeString denotes a string type.
DefaultUserAgent which is set on outgoing http requests if none is set on the client.
DocumentIndexingExclude specifies that the document should be excluded from the collection index.
DocumentIndexingInclude specifies that the document should be included in the collection index.
ErrKeyNotFound is returned when the required key was missing from the response object.
ErrOfferInvalidVersion is returned when an invalid offer version is read.
ErrPreconditionFailed is returned when an optimistic concurrency check fails.
ErrResourceNotFound is returned when a resource is not found.
HeaderActivityID "x-ms-activity-id" See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderAIM is sued to indicate the Change Feed request.
HeaderAltContentPath is the alternate content path of the resource.
HeaderAuthorization is the header used to pass the Authorization token to the API.
HeaderConsistencyLevel Strong, Bounded, Session, or Eventual (in order of strongest to weakest) See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderContentType is used mostly for POST query operations where the Content-Type header must be application/query+json See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderContinuation represents the intermediate state of query (or read-feed) execution, and is returned when there are additional results aside from what was returned in the response.
HeaderDate is the date time of the response.
HeaderDocDBIsQuery is used to indicate the POST request is a query, not a Create.
HeaderDocDBIsUpsert is set to true if the document should be created if it does not exist, or updated in-place if it does.
HeaderDocDBPartitionKey the partition key value for the requested document or attachment.
HeaderDocDBPartitionKeyRangeID Used in change feed requests.
HeaderDocDBQueryEnableCrossPartition is set to true for queries which should span multiple partitions, and a partition key is not supplied.
HeaderETag indicates the etage of the resource.
HeaderIfMatch used for optimistic concurrency based off ETag See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderIfModifiedSince used for optimistic concurrency based off Modified Date (RFC1123 Date/Time Format) See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderIfNoneMatch used for optimistic concurrency based off ETag See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderIndexingDirective is used to enable or disable indexing on the resource.
HeaderItemCount is the number of items returned for a query or read-feed request.
HeaderMaxItemCount is supplied in list/query operations to limit the number of results per page.
HeaderMSAPIVersion is used to specify which version of the REST API is being used by the request See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
HeaderMSDate is the date/time of the request.
HeaderOfferThroughput is used to set the provisioned RU Throughput on the collection at creation time.
HeaderOfferType is used to set the Offer type on the Collection at creation time.
HeaderRequestCharge is the number of normalized requests a.k.a.
HeaderResourceQuota is the allotted quota for a resource in an account.
HeaderResourceUsage is the current usage count of a resource in an account.
HeaderRetryAfterMS is the number of milliseconds to wait to retry the operation after an initial operation received HTTP status code 429 and was throttled.
HeaderSchemaVersion Shows the resource schema version number.
HeaderServiceVersion is the service version number.
HeaderSessionToken is the session token of the request.
HeaderUserAgent used to differentiate different client applications.
IndexingModeConsistent means the index is updated synchronously on each insertion, replacement, or deletion action taken on a document in the collection (MSFT).
IndexingModeLazy means the index is updated asynchronously and may be out of date, eliminating the ability to consistently "read your writes".
IndexingModeNone means no indexing is performed at all.
MasterTokenAuthType specifies that the type of authentication used is 'master' when computing the hash signature for an authenticated REST API call.
OfferTypeInvalid indicates the performance level is user-defined.
OfferTypeS1 maps to the S1 performance level.
OfferTypeS2 maps to the S3 performance level.
OfferTypeS3 maps to the S3 performance level.
OfferV1 uses a set list of OfferTypes.
OfferV2 allows tunable request unit throughput.
PartititionKindHash is used to enable equality comparisons.
PartititionKindRange is used to enable sorting and range comparisons.
PartititionKindSpatial is used to enable spacial queries (such as geographic coordinates).
ResourceAttachments is the resource type of an Attachment.
ResourceCollections is the resource type of a Collection.
ResourceDatabases is the resource type of a Database.
ResourceDocuments is the resource type of a Document.
ResourceOffers is the resource type of an Offer.
ResourcePermissions is the resource type of a Permission.
ResourceStoredProcedures is the resource type of a Stored Procedure (sproc).
ResourceTriggers is the resource type of a Trigger.
ResourceUserDefinedFunctions is the resource type of a User-Defined Function (udf).
ResourceUsers is the resource type of a User.
TokenVersion is the version of the token that is implemented See https://docs.microsoft.com/en-us/rest/api/documentdb/access-control-on-documentdb-resources for more information.

# Structs

Client for making API calls against CosmosDB.
ClientRequest encapsulates the CosmosDB API request parameters.
CollectionClient is a client scoped to a single collection Used to perform API calls within the scope of the Collection resource.
CollectionExcludedPath represents a JSON Path to exclude from indexing inside a CollectionIndexingPolicy.
CollectionIncludedPath represents a JSON Path and the type of data to include when indexing.
CollectionIndex describes the type of data and precision that an included indexing path should used when being indexed.
CollectionIndexingPolicy represents the indexing policy configuration for a Collection.
CollectionPartitionKey specifies the partition key indexing config.
CollectionResource represents a Collection container in Cosmos DB Documentation adapted from adapted from docs.microsoft.com See https://docs.microsoft.com/en-us/rest/api/cosmos-db/collections for the latest documentation.
CommonRequestOptions is a helper which adds additional options to their appropriate headers in the CosmosDB HTTP request The specific options which are permitted varies depending on the request See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers.
ConnectionString is the connection string for accessing a storage account.
CreateCollectionRequest captures the request options for creating a new Collection.
CreateDocumentRequest are parameters for CreateDocument.
CreateStoredProcedureRequest are parameters for CreateStoredProcedure.
CreateUserDefinedFunctionRequest are parameters for CreateUserDefinedFunction.
DatabaseClient is a client scoped to a single database Used to perform API calls within the scope of the Database resource.
DatabaseResource represents a Database in Cosmos DB Documentation adapted from adapted from docs.microsoft.com See https://docs.microsoft.com/en-us/rest/api/cosmos-db/databases for the latest documentation.
DocumentClient is a client scoped to a single document Used to perform API calls within the scope of a single Document resource.
DocumentProperties are the well-known properties that may exist on a Document resources.
OfferClient is a client scoped to a single offer Used to perform API calls within the scope of the Offer resource.
OfferContent encapsulates the different offer schemas depending on OfferVersion.
OfferContentV2 is the content of the OfferVersion "V2" for user-defined throughput.
OfferResource represents a performance-level offering on a resource.
Query encapsulates a SQL-like query on the Collection Parameters can be added by using the AddParameter method Additional query options can be addy by supplying a QueryOptions.
QueryParameter encapsulates a named query parameter for a query along with its value.
ReplaceDocumentRequest are parameters for CreateDocument.
ReplaceOfferRequest encapsulates the offer to replace.
ResponseMetadata is the parsed header values from the response See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-response-headers.
SProcClient is a client scoped to a single stored procedure Used to perform API calls within the scope of the Stored Procedure resource.
StoredProcedureResource represents a Stored Procedure in Cosmos DB Documentation adapted from adapted from docs.microsoft.com See https://docs.microsoft.com/en-us/rest/api/cosmos-db/collections for the latest documentation.
UDFClient is a client scoped to a single user-defined function Used to perform API calls within the scope of the UDF resource.
UserDefinedFunctionResource represents a User Defined Function in Cosmos DB Documentation adapted from adapted from docs.microsoft.com See https://docs.microsoft.com/en-us/rest/api/cosmos-db/collections for the latest documentation.

# Interfaces

Authorizer is an interface used to authorize Cosmos DB Requests.
Requester is an interface for sending HTTP requests and receiving responses *http.Client implicitly implements this interface already But more complicated logic such as logging are possible here as well.
RequestOptions augments the request, such as adding headers, or query parameter to an existing http.Request.

# Type aliases

ConsistencyLevel specifies the consistency level of the operation See https://docs.microsoft.com/azure/cosmos-db/consistency-levels for more information.
DataType is the data type used for indexing.
DocumentIndexingDirective determines if a document create/update should be indexed.
Error is an interstellar generated error This type is an alias for 'string' and is used to ensure the interstellar sential errors can be made constant.
IndexingMode specifies how indexing will be performed on each insertion, replacement, or deletion action.
MasterKey is the shared key for the storage account.
OfferType is used to specify the pre-defined performance levels for the CosmosDB container.
OfferVersion differentiates different offer schemas.
PaginateCollectionResource pagination function for a list of CollectionResource.
PaginateDatabaseResource pagination function for a list of DatabaseResources.
PaginateOfferResource pagination function for a list of OfferResource.
PaginateRawResources is run by the List* operations with each page of results from the API.
PaginateSProcResource pagination function for a list of StoredProcedureResource.
PaginateUDFResource pagination function for a list of UserDefiendFunctions.
PartitionKind is the kind of index used for equality or range comparison.
RequestOptionsFunc implements RequestOptions for a pure function Can be used to apply options with an anonymous function such as RequestOptionsFunc(func(req *http.Request) { ..
RequestOptionsList implements RequestOptions for a list/slice of RequestOptionsListRequestOptionsList.
ResourceType indicates the type of resource being requested.