Engineering Blog Atom Feed

Nate Harris

Major Improvements Coming To Our Client Libraries

by Nate Harris

When it comes to interacting with the EasyPost API, the overwhelming majority of our customers choose to use our client libraries. These libraries offer complete coverage of nearly all available API features, including beta features, come in a variety of languages to meet your needs regardless of your tech stack, and generally make working with the EasyPost API much simpler by handling a lot of the heavy lifting.

We at EasyPost are constantly updating and improving our client libraries to make them as easy and user-friendly as possible, and even spun up the dedicated Developer Experience team late last year to do just that.

With that in mind, we would like to alert you to some major improvements coming to the client libraries in the coming months.

Why the change?

Starting with our .NET library, each of our client libraries will be undergoing a redesign. These redesigns aim to introduce thread-safety to our libraries, as well as tackle a number of inconsistencies and oddities that have been introduced as our API has grown over the years.

Currently, all of our client libraries, with the exception of our Go library, are considered thread-unsafe due to how API keys are set and used in the libraries. This limitation makes it difficult to switch between multiple API keys and, in a multi-threaded environment, may accidentally lead to the wrong API key being used for an API request. This issue has been reported to us by our users and has been our top priority to fix since the Developer Experience team was started last year.

In the coming days, we will be rolling out a release candidate for v4.0.0 of our .NET client library. This library has undergone an overhaul, with many aspects of the library completely redesigned from the ground up. At the same time, we understand that updating often poses a challenge for end-users. We wanted to improve as much as possible while also requiring as little work as possible from end-users to implement the new library version.

How does the new design work?

Let's take a brief look at how the new client library will work. A complete upgrade guide is available on our GitHub repository.

First off, to remove the global API key concept that caused the thread-unsafeness, we have re-architected the library to be instance-based. Rather than setting a global API key via the ClientManager, an end user will create an instance of a Client object using a specific API key.

Old method:
  
EasyPost.ClientManager.SetCurrent(“MY_API_KEY”);
  
New method:
  
Client myClient = new Client(“MY_API_KEY”);
  

The API key will be tied to the Client object; any requests made with the Client will use the API key. This API key cannot be modified once set; to change the API key, create a new Client instance with the new key.

In a multi-threaded environment, end-users should create a Client instance for each API key used, and use each instance accordingly.

Because the library now revolves around a Client instance, services are now accessed via the Client object.

Any "static" methods such as Create, Retrieve or All are summoned via a specific service on the Client.

Old method:
  
Shipment myShipment = await Shipment.Create(parameters);
  
New method:
  
Shipment myShipment = await myClient.Shipment.Create(parameters);
  

In the example above, the API key tied to the myClient client will be used to create a new Shipment object. The client object will then be associated with the Shipment object and any sub-objects (such as Address, Parcel, etc.)

Because the Shipment object is tied to the client, instance-based methods for a shipment (i.e. Buy, GenerateForm, etc.) do not need to be called against the myClient object. The client and its API key, however, will still be used for any API calls automatically. You as an end-user will not need to keep track of what API key was used to create a given object.

Old method:
  
await myShipment.Buy(parameters);
  
New method:
  
await myShipment.Buy(parameters);
  

As you can see, the syntax for this function has not changed, meaning no alterations required by an end-user.

As noted before, all services are accessed via a Client instance. Beta services are available under the Beta property of a Client instance.
  
AddressService myAddressService = myClient.Address
SomethingBetaService mySomethingBetaService = myClient.Beta.SomethingBeta
  

It is also important to discuss data flow with our client libraries. The majority of our libraries, with the exception of our Node.JS library, work by making API calls first and then serializing the response from our API into a local object. This server-side-first flow means that any local object (e.g. an Address object) is simply a mirror of server-side data. When local objects are "updated", an API call is made and the local object is then altered to match the new data echoed by the API. Because of server-side data validation, sometimes the local object will look slightly different than the parameters used to "create" it (e.g. names may be capitalized or formatted).

To preserve this data flow, the library has been designed so that end-users cannot create objects directly; objects can only be made via a Create, Retrieve or All API call from a service.

Invalid method:
  
Shipment myShipment = new Shipment(myData)
  
Correct method:
  
Shipment myShipment  = await myClient.Shipment.Create(myData)
  

Another major callout for the upgrade is our improvements to following language conventions. We use a lot of Python here at EasyPost, and as a result, a lot of our client libraries were written from a Python perspective. If you've ever used our .NET or Java client libraries, you might have noticed that a lot of properties and methods use snake case rather than Pascal case or camel case (trust us, our IDEs have been upset about it for years now).

With the overhaul, we took the opportunity to rectify this issue. All properties and methods in the .NET library are now properly pascal-cased. We will continue this enhancement, as needed, for the remaining client libraries.

When is the new release coming?

Additional, smaller improvements have been called out in our Upgrade Guide on our GitHub repository for the .NET library. If you are a .NET user, please check the guide to verify any work that may need to be done to integrate with the new library version. There's also several minor under-the-hood improvements we made during this redesign; feel free to explore our source code.

Once the Release Candidate has had enough time out in the wild, we will make an official v4.0.0 release of the .NET library. We do not have a specific release date yet.

Once the .NET release is official, we will be migrating our other client libraries to this new design. We anticipate that the next major version of each client library will be the redesign, so be on the lookout. If you want to avoid an accidental upgrade to the new version, please pin the current major version in your application; our Pinning Guide can help you with that.