1

We are building API which mainly passes database objects back and forth between user and database, so the main flow of information is quite basic:

Table (view) <-- ORM --> C#/Java/etc. Objects <-- JSON serializer --> JSON objects <-- HTTP --> User

We are using ASP.NET Core with Entity Framework Core if it matters, but I believe this is at least somewhat technology agnostic question.

Most of our backend objects mapped from DB do contain lots of optional properties, meaning that they are nullable in the database. Of course, this would imply that those properties should also be Nullable/Optional/WhateverInYourLanguage in the object-oriented world.

Now the problem arises when the user would want to set one existing property of some object to null. We could then receive maybe following kind of update JSON from the user (lots of details omitted and the structure is stupid, don't mind about that):

{
    "TargetType": "Foo",
    "Id": 65,
    "NullableProperty": null
}

So the user would want to set the value of property NullableProperty to null for an object with the type of Foo and with Id of 65. All well and good so far.

First, we were thinking of generating an object of type Foo from received JSON and updating existing database object with that, but this would lead to a situation where all of the created object's properties would be null, so how would we know what properties to update?

Other solution could maybe be to have update function which would have all optional property parameters set to null, but this would lead to the same problem, would null mean that value for that property was not provided or user-provided null value?

Then we thought that user would have to send whole data object through json, which would contain all the needed values and they would be just copied to the database object. This won't do for multiple reasons (many times users are provided just parts of an object, object sizes may be quite large, there is a risk of losing data, etc.)

One other way which we are not too eager to implement is to reserve some special value to mean null for each data type. For example date 9999-99-99 could mean null for dates, number MinInt would mean null for integers and "" would be null for strings, etc. This could work maybe at least for some extent, but even now it makes me cringe to think about this.

Is there some good design pattern for these kinds of situations? I have given this now some thought, but I cannot seem to reach better conclusions than listed above.

2
  • you should send the full object with null fields set to whatever null serialisation your deserializer understands (json.net?) It seems like the real problem is why you are unable to do that and how to get around it
    – Ewan
    Commented Oct 10, 2018 at 8:56
  • @Ewan You may have a point. Our API is one part of the larger project we are working with, so introducing full objects would be a change that we would need to discuss with other teams also. Using always full objects would seem however to introduce lots of overhead since otherwise updating objects would be no problem. Clearing values of objects seems at this point to be only minor nuisance which should be taken care of. That's also why I'm exploring also other options. Commented Oct 10, 2018 at 10:08

1 Answer 1

4

If your JSON API allows partial objects to be sent for updates (as in, a request to update object 65 of type Foo contains only a subset of the properties of type Foo), then the most sensible approach is that the properties that are not mentioned in the JSON description will not be modified.

This means that if you get an update request with the JSON document

{
    "TargetType": "Foo",
    "Id": 65,
    "NullableProperty": null
}

then you process it like this:

  1. Retrieve the object of type Foo with Id 65 from the database
  2. Modify NullableProperty to set it to NULL, leaving all other properties unchanged
  3. Update the database with the modified object

This means that if a property should be set to NULL, then it must be explicitly mentioned on the JSON interface.

4
  • Yes, this way using JSON would be the cleanest and this is what we already thought of using. But the problem with this approach is that we have automatically generated ORM objects in the backend and backend automatically deserializes received JSON objects. Thus if we had also a property named AnotherNullableProperty, its value would be also null because user did not provide any value for it. Then we would not know which properties to really clear. Commented Oct 10, 2018 at 11:24
  • @TuomasKujala: How does the backend react when Foo has a property that is not nullable, but it is absent from the JSON object? Commented Oct 10, 2018 at 11:36
  • Actually to keep things simple, I left out part that we have kind of message preprocessor, which among other things validates incoming messages against a schema. So the kind of message you described would be erroneous since it wouldn't contain all needed information. Commented Oct 10, 2018 at 12:47
  • @TuomasKujala, I get a very strong feeling that the tooling/libraries that you use for the ORM and/or serialization to/from JSON simply don't match with your requirements. In that case, you need to look for new tools/libraries that better fit your needs and possibly write more code yourselves. Commented Oct 10, 2018 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.