Skip to content

Draft: Migration from v2 to v3 SDK

j82w edited this page Jun 30, 2020 · 6 revisions

Draft Migration from v2 to v3 SDK

At the high level the big difference between v2 and v3 SDK are mostly cosmetic like renames and the new fluent hierarchy that replaces the URI factory. The networking, retry logic, and lower levels of the SDK are mostly the same.

Name Changes

Concepts

These changes were made to make them more generic to better work with all the different Cosmos DB offerings.

  1. Collection -> Container
  2. Documents -> Items

Classes

  1. DocumentClient -> CosmosClient
  2. ConnectionPolicy -> CosmosClientOptions
  3. DocumentClientException -> CosmosException
  4. All resource objects appended Properties to the name
    1. Database -> DatabaseProperties
    2. DocumentCollection -> ContainerProperties
    3. StoredProcedure -> StoredProcedureProperties
    4. Trigger -> TriggerProperties
  5. New client side references and are used to help create the URL. Creating a reference does not validate that it exist in Cosmos DB. This also creates a object model which helps the user see all the methods that can be used for that reference. In the v2 SDK all the methods were directly off the client making it difficult to find methods.
    1. Database, Container, User, Permission, Scripts, Conflict

Settings

  1. v3 defaults to Direct + TCP because it gives better performance and scalability over Gateway + HTTPS.

Removed

  1. UriFactory is replaced by the Fluent design. The fluent design builds the URLs internally which allows a single Container object to be passed around instead of a DocumentClient, DatabaseName, and collection name.
  2. Document and Resource class do not exist in v3. A lot of issues were caused by these classes. For example the Document class would sometimes not serialize properties if they were not properly set.
  3. Document id is not auto populated in v3. To auto populate the id it requires the document to be parsed and checked if the id exists which causes an unnecessary performance hit for most users. There even some users that were doing a query after the create to figure out auto generated id. An Extension Method can be implemented to add the same functionality.

Added

  1. TransactionalBatch
  2. Bulk
  3. Change feed
  4. Stream APIs which for some scenarios avoids an additional serialization cost.

Examples

Basic example of creating a database, container, and item

V3 SDK

// The client should be a singleton for the application
using (CosmosClient client = new CosmosClient(endpoint, authKey))
{
    // An example if you need to create database and container
    Database database = await client.CreateDatabaseIfNotExistsAsync("MyDatabase");
    Container container = await database.CreateContainerIfNotExistsAsync(
         containerProperties: new ContainerProperties(id: "TestContainer", partitionKeyPath: "/id"),
         throughputProperties: ThroughputProperties.CreateAutoscaleThroughput(10000));
    
    // If you have an existing container that does not need to be created or verified it exists
    container = client.GetContainer(databaseId: "MyDatabaseId", containerId: "TestContainer");

    // Creates a random item
    ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
    ToDoActivity createdItem = await container.CreateItemAsync<ToDoActivity>(item: testItem);

    ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(
         partitionKey: new PartitionKey(testItem.Id),
         id: testItem.Id);
}

V2 SDK

// V3 SDK defaults to Direct + TCP, V2 SDK defaults to Gateway + HTTPS
ConnectionPolicy connectionPolicy = new ConnectionPolicy();
connectionPolicy.ConnectionMode = ConnectionMode.Direct;
connectionPolicy.ConnectionProtocol = Protocol.Tcp;

// The client should be a singleton for the application
using (DocumentClient client = new DocumentClient(new Uri(endpointUrl), authorizationKey, connectionPolicy))
{
    string databaseName = "MyDatabase";

    // An example if you need to create database and container
    Database database = await client.CreateDatabaseIfNotExistsAsync(new Database { Id = databaseName });
    DocumentCollection collectionDefinition = new DocumentCollection();
    collectionDefinition.Id = "TestContainer";
    collectionDefinition.PartitionKey.Paths.Add("/id");
    
    // V2 SDK does not support creating autoscale offers
    DocumentCollection collection = await client.CreateDocumentCollectionIfNotExistsAsync(
        UriFactory.CreateDatabaseUri(database.Id),
        collectionDefinition,
        new RequestOptions { OfferThroughput = 10100 });
    
    Uri collectionLink = UriFactory.CreateDocumentCollectionUri(database.Id, collection.Id);

    // Creates a random item
    ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
    ToDoActivity response = (dynamic)(await client.CreateDocumentAsync(collectionLink, testItem));

    // Read an item
    ResourceResponse<Document> response = await client.ReadDocumentAsync(
         UriFactory.CreateDocumentUri(database.Id, collection.Id, testItem.Id), 
         new RequestOptions { PartitionKey = new PartitionKey(testItem.Id) });
}