When should null properties be ignored on REST API responses? - json

I'm developing a web api for common CRUD operations (entities like Products, Categories) and I want to know pro/cons to suppress null properties and what should I take care choosing to ignore or not ignore these fields.
Example:
{
"name": "Product A",
"description": null
}
or
{
"name": "Product A"
}

If the client send an explict null he wants to delete the value for this property. In your first example he wants to delete the description value.
If the client does not send a property at all, he wants to leave the value of the property unchanged. In your second example he wants to leave the value of description and all other properties except name unchanged.

While you are creating new record no issues with both.But while you updating a new record if you pass null for description the record already in the db for description will be deleted, if you don't pass anything the record already in db will exist as it is.

Related

How to dynamically avoid sending response containing all properties from relationship data

I am new to spring boot and rest and hence pardon me if this question is very trivial.
I have a situation where the application allows users to register and place order.
On registration of user, the service should be able to send a response with the user information including - User Name, email, contact Number, address etc.
However, while placing orders, I would like the order response object to include within the order details, only the customer (username, email). I do not want to include the address and other information part of the User object.
Currently, what is happening is whenever, I refer to an existing user instance within the Order instance, the Order response has the complete tuple information of the registered user.
In the Order confirmation response, I really do not want the entire User information.
However, if the same Order entity is being referenced for user register, I want the service to include all fields from the Order entity.
I have tried referring to the following links -
Jackson Change JsonIgnore Dynamically
How do I exclude fields with Jackson not using annotations?
However, the solutions mentioned here will always ignore the attribute in response irrespective of the scenario in which the entity is being referenced.
For example - Response from Order service is as below.
{
"id": "ORD-1000",
"priority": null,
"status": "Open",
"customer": {
"id": "1000",
"name": "Avion Solutions",
"email": "support-na#avionsolutions.com",
"contact": null,
"customerType": "gold-sx",
"shipToContactId": null,
"billToContactId": null
},
"urgency": null
}
In the above response tuple, lets say, I just want the order information with basic customer information such as name & email.
And if the customer is registering, then the response should contain all the information as mentioned in the above tuple.
How can i dynamically ignore the attributes in response of the REST service based on the context in which the entity object is being used?
Thanks in advance.
Try to use #JsonView annotation. You can define visibility for given property and on REST Controller you can define level you want to show. For more information and examples, please, read below:
Jackson JSON Views
Jackson – Bidirectional Relationships
Using #JsonView with Spring MVC

Postgresql Update JSON Column Retaining Some KeyValues and Adding Additional KeyValue as null

I am trying to use a metadata JSONB column for a multi-tenant application. Every user for each tenant must have the same metadata, but the tenants have varying metadata fields.
In order to keep all user metadata in sync per tenant, when the tenant admin modifies the metadata fields I need to make sure all users have their metadata JSONB column updated with the following criteria:
If the metadata field/key already exists, the value needs to be retained
If the metadata field/key is new, the key needs to added with a null value
If there are any metadata fields/keys that are not included in the updated list, they should be deleted from the JSON object
For example, all the users for Tenant #1 have the following metadata assigned: { "EmployeeNo" : 123, "HireDate" : "2012-10-10", "Age" : 43 } and somewhere down the line the admin decides they don't care about Age, but they do want to start tracking ParkingSpace.
I need the new metadata record to retain the EmployeeNo and HireDate values, remove the Age key/value, and add the ParkingSpace key with a null value. { "EmployeeNo" : 123, "HireDate" : "2012-10-10", "ParkingSpace" : null }.
I would have thought that I could run an update query similar to the following where it returns a JSONB object where it selects the values if the key exists and a null if it doesn't:
UPDATE users SET metadata = metadata[keys: 'EmployeeNo', 'HireDate', 'ParkingSpace'] WHERE tenant_id = 1;
Obviously that won't work, but hopefully it indicates the issue?
Update: I might have misunderstood your question. Maybe you wanted something like that instead:
UPDATE users
SET metadata = (SELECT json_object_agg(n,metadata->>n) FROM unnest(ARRAY['EmployeeNo','HireDate','ParkingSpace']) AS t(n))
This solution involves creating a brand new jsonb object by extracting only the field that you want from the original metadata. The fields to be copied over are specified as an array that you can easily customize.
Original answer: I think this should do it:
UPDATE users
SET metadata = (metadata - 'Age') || '{"ParkingSpace": null}'::jsonb;
I am using the || operator which merges 2 jsonb objects into one and the - operator which removes a key/value pair.

Updating particular field in REST call jpa

Am new to REST webservice, i have a scenario where each field in a form to be save to the database as when user fills the field.
So am calling an update API when user goes from one field to another. Using jpa for database operation. The problem am facing here is, lets say for example Employee.
{
"fname":
"lname":
"mname":
"addresses":
{
"line1":
"line2":
}
}
While user fills fname my json will be
{
"fname":"some value"
}
ill call rest to update. And for next field
{
"lname":"another value"
}
in this update case lname will be updated but fname updated with a blank value since am not passing fname. So i have to send full json to have a proper value.
Think if my json is too big with many relation, am feeling just to update one field its not good to pass complete json to the REST API's.
Can somebody give me any idea or any solution for this.
Am developing this with Spring-boot framework
Thanks in advance.

Insert all domain members into Group

I'm currently writing an Add-on to manage Google Groups, and it uses the Admin SDK Directory API to loop through and retrieve all group members and make changes etc.
One curious issue I've found is that when 'All members of the domain' have been added to the group, no member email is supplied. For example, if I retrieve all members of the group, each member will be returned in the format:
{
"kind": "admin#directory#member",
"etag": "\"ABCDEFGHIJKLMNOPQRSTUV123456789\"",
"id": "123455678910",
"email": "email#myDomain.com",
"role": "MEMBER",
"type": "USER"
},
However, if you've added all users within the domain to a group, when you retrieve this 'member', it's returned in the format:
{
"kind": "admin#directory#member",
"etag": "\"ABCDEFGHIJKLMNOPQRSTUV123456789\"",
"id": "123455678910",
"role": "MEMBER",
"type": "CUSTOMER"
},
This is fine for retrieval, as I can identify that it's 'All users in the domain' by the 'type' always being 'Customer', then I just give it an arbitrary email address to display in my interface (I'm using '*#domain.com' just because).
However, when I'm updating the group members list using the 'Insert' method, it requires an email Address (It refers to 'memberkey', but I understand that this must be an email address).
It won't accept dummy addresses such as *#domain.com (It returns an error that this particular address exists, so I gues it's in use in the background), and if I use an existing address and try to overwrite the 'type' from 'User' to 'Customer' in an attempt to convert an existing member to the 'All users' value, this doesn't work (I suspect the 'type' field does not allow 'Customer' as a writable field, only a readable one).
My question: There does not seem to be a method to 'Add all users in the domain' to a group neatly, without looping through the domain and literally adding all members one by one. Does this method exist and I've just missed it? Or is there a neater way to add all members to the group without looping through all the members on the domain and adding them to the group one by one?
No API method has existed for this even back into the provisioning API days. Nothing in Group Settings is different for a group of this kind, it seems to be an unsupported Member Resource. Trying to modify existing members to become type: 'CUSTOMER' also fail.
You can, however, set a single group in the Admin Panel UI to be your "All Members" and then use the address of that group as a proxy member. i.e. it is a propagated all member feature. This is a workaround as opposed to a direct answer, but as I state above the real answer is "No".

MailChimp Interested Value in "Group" always false after "subscribing"

I send over proper json formatted code, according to v2 api docs:
lists/subscribe.json
"GROUPINGS":[{"id":removed_id,"name":"grouping_name","groups":["group_name"]}]
I get back information about a member... It does not say they are interested in that group name..
lists/member-info.json
"GROUPINGS":[{"id":removed_id,"name":"grouping_name","form_field":"hidden","groups":
[{"name":"group_name","interested":false},{"name":"other_group_name","interested":false},
{"name":"other_group_name2","interested":false},{"name":"other_group_name3","interested":false}]}]
I do not understand how I can get these users to show up as "subscribed" to a group within my grouping. I have been trying for nearly 5 hours now. I have tried:
making sure the groups: value is an [] array.
trying out making that value a string (which surprisingly did not throw errors)
capitalizing "GROUPINGS" when sending it in merge_vars
not capitalizing "groupings" when sending in merge_vars
using the lists/update-member.json method to update these groups
using the name of my interest group instead of grouping in the grouping array.
using the option replace_interests on both true and false
In conclusion,
I had to email mailchimp a support ticket. Without changing my code at all - it works this morning. Interestingly enough, mailchimp was experiencing many issues yesterday with servers being down and alleged email hackings.
To be clear about which version of my code worked - following the API exactly for v2.
It was an error on mailchimp's end.
{
"id":"MY LIST ID",
"email":{
"email":"THE EMAIL TO SUBSCRIBE"
},
"merge_vars":{
"GROUPINGS":[
{
"id":THE GROUPING ID,
"groups":[
"THE NAME OF MY GROUP"
]
}
]
},
"double_optin":false,
"replace_interests":true,
"apikey":"MY API KEY"
}
Also, in case you are curious, replace_interests is true when the groups you send are supposed to replace existing groups the subscriber is interested in. False indicates that the groups you pass should be added to the interest groups.
If you are updating a member (method: lists/update-member), it may be best to set replace_interests to false just to make sure it does not overwrite your existing interest groups (possibly with blank groups). The default value for it is true, so this could be another place prone to error.