ShopifySharp runs into an issue that many C# libs find themselves facing: non-nullable types and POST/PUT requests don't mesh that well. For example, take the following class:
public class MyObject
{
public int Id { get; set; }
public DateTime Created { get; set; }
public double Price { get; set; }
public bool Active { get; set; }
}
Suppose that we need to create a "MyObject" through the Shopify API, but the POST option expects just the Price
property. We create a new "MyObject" like so:
var myObj = new MyObject() { Price = 123.00 };
And we send that object to our pretend API. However, because of the way C# works with non-nullable types, C# will send the following:
{ "id": 0, "created": "0001-01-01T00:00:00", "price": 123.00, "active": false }
That's not good. The API only wanted the price, but C# sent an empty Id and Created date, and a false Active flag too. This isn't a huge problem when using POST endpoints because Shopify will typically just ignore the extra stuff it isn't looking for.
The big problem is working with updates to objects through PUT requests. Suppose you now want to update just the Active property for an object that was already created. You create your object like so:
var myUpdatedObj = new MyObject() { Active = true };
But when you send it, C# serializes it into this:
{ "id": 0, "created": "0001-01-01T00:00:00", "price": 0, "active": true }
Now that's a big problem. Active got set to true
, but the object's price was just set to 0 too. You probably didn't want to do that, but thanks to C#'s non-nullable types it happened anyway without any input from you. The only way to avoid doing this is to pull the object from the API first, then make changes to that object and send the whole object through the update.
That's far from ideal; now updating an object goes from one request to two, and wastes bandwidth too. For ShopifySharp 3.0, I'm looking into ways to prevent sending unnecessary information through POST and PUT requests. I have two solutions right now, but welcome any suggestions:
- Make all non-string properties nullable. Drawback is that you now have to check if a prop has a value when operating on an object (e.g.
Created.Value.ToShortDateString()
instead of Created.ToShortDateString()
).
- Create separate classes for creating and updating an object, akin to the way Stripe.net handles create/update requests. Drawback is a lot of duplicated code, and making changes to one object will need to be reflected to its create/update objects too.