Exclude non-required attributes when rendering media type

9 views
Skip to first unread message

Sean McGivern

unread,
Feb 20, 2015, 10:57:46 AM2/20/15
to praxis-de...@googlegroups.com
We have a media type with a lot of non-required attributes (let's say 10+). Depending on the params passed, any number of these can be in the response. Those which we don't provide to be rendered are still filled in with nil values, which clutters up the response JSON. There's an example below; here are the options as I see them:
  1. We change Praxis to either by default or with an option, only serialise values which are present when rendered (assuming they aren't required, and don't have a default).
  2. We manually strip nil values from the response where we know they aren't needed, before returning to the client.
  3. We just deal with it.
  4. We define a different view for each combination of these columns, and use the appropriate view.
4 is obviously a terrible idea given the number of combinations possible, not to mention the naming problems. We're not going to do 3, because although gzip will probably take care of bandwidth problems, we'll still have a bunch of irrelevant information to look through when we're looking at the raw responses. We can do 2, but this seems like a framework-level feature to me, which brings us nicely to the first option!

I'm interested in what other people think about this, and what the use cases are for passing the nils for non-required attributes.

Here's the example:

# the media type has:
attributes do
  attribute :timestamp, DateTime
  attribute :metrics do
    METRICS.each do |metric|
      attribute metric, Float
    end
  end
end

view :default do
  attribute :timestamp
  attribute :metrics
end

# we get a request which implies that only the total cost will be rendered:
GET /api/current/total_cost

# we respond with just total cost and a timestamp, and the default view
V1::MediaTypes::Current.new(OpenStruct.new(timestamp: Time.now, metrics: {total_cost: 1})).render(:default)

# and we get every metric
{
  timestamp: Fri, 20 Feb 2015 15:40:55 +0000,
  metrics: {
    total_cost: 1.0,
    another_metric: nil,
    # ad nauseum
  }
}

Thanks!

Sean

Josep Blanquer

unread,
Feb 23, 2015, 4:05:19 PM2/23/15
to Sean McGivern, praxis-de...@googlegroups.com
Sean,

 The reporting of "nil" values was something that some people asked to explicitly list. I don't recall the exact reason, other than having to do with the client somehow knowing what possible fields to encounter. (Maybe somebody in the list can shed light on the exact reasons at the time).

I personally don't like it at all, and I'd be 100% inclined to change it. In particular, because the clients should be able to consume the JSON generated documentation if they want to see what possible fields a given MediaType could have...

 But before changing that behavior, I'd like to hear about more people either wanting the change, or preferring the current format of explicitly listing all attributes (with "nil" if there's no value for them)

What say you?

BTW: This is a change in the praxis-blueprints gem, not even Praxis the framework.

Josep M.

--
You received this message because you are subscribed to the Google Groups "praxis-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to praxis-developm...@googlegroups.com.
To post to this group, send email to praxis-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/praxis-development/02e99d7e-a44f-443f-8906-b051f0a4c8a2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ryan Williamson

unread,
Feb 23, 2015, 8:08:18 PM2/23/15
to Josep Blanquer, Sean McGivern, praxis-de...@googlegroups.com
If the fields can be divined from the generated json metadata for building clients I see no reason to explicitly listing all the attributes.  In fact I would prefer them not to be if there is no value for them.  Just my .02.

-Ryan

Josep Blanquer

unread,
Feb 25, 2015, 11:55:47 AM2/25/15
to Ryan Williamson, Sean McGivern, praxis-de...@googlegroups.com
What does everybody think about adding an option to the `.render` method of a MediaType/Blueprint so that one can choose if to include null fields or not?

It'd be going from:
MyMediaType.new( obj ).render(:default)

To:
MyMediaType.new( obj ).render(:default, include_nulls:true)

and I'd make the default "false" so the default outputs are more compact, as it was the initial as in this thread.

Thoughts?

Josep M.

Sean McGivern

unread,
Feb 25, 2015, 12:41:38 PM2/25/15
to Josep Blanquer, Ryan Williamson, praxis-de...@googlegroups.com
Sounds good to me.

Justin Gaylor

unread,
Mar 2, 2015, 3:49:35 PM3/2/15
to praxis-de...@googlegroups.com, blan...@rightscale.com, ryan.wi...@rightscale.com
I may have been one of the people originally thinking that it could benefit the clients. But I agree that the metadata is the source for that info, so I also like the option approach. No reason to force everyone one way or the other. 

Where should the enhancement for this feature go? I'm guessing praxis-blueprints?

Cheers,
Justin
Sounds good to me.

To unsubscribe from this group and stop receiving emails from it, send an email to praxis-development+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "praxis-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to praxis-development+unsub...@googlegroups.com.

To post to this group, send email to praxis-de...@googlegroups.com.

Josep Blanquer

unread,
Mar 18, 2015, 8:24:54 PM3/18/15
to Justin Gaylor, praxis-de...@googlegroups.com, Ryan Williamson
ok, just to follow up on this...the Praxis gem we released yesterday includes this feature.

You can read a little more about it in the media_types document, under the views section (http://praxis-framework.io/reference/media-types/)

In short, a view can define if nils must be rendered or not. Here's a quick excerpt:

By default, a view will not render attributes whose values are nil. This can be overrided by passing include_nil: true when defining the view. For example:

class Blog < Praxis::MediaType
  view :partial, include_nil: true do
    # ...
  end
end


Happy Praxing,

Josep M.
Reply all
Reply to author
Forward
0 new messages