Skip to content

Filter data structures for "partial responses," Google style

License

Notifications You must be signed in to change notification settings

shutterstock/Data-Partial-Google

Repository files navigation

package Data::Partial::Google;
# ABSTRACT: Filter data structures for "partial responses," Google style
# VERSION
# AUTHORITY
use Moo;

use Data::Partial::Google::Parser;
use Data::Partial::Google::Filter;

has rule => (
	is => 'ro',
);

has filter => (
	is => 'ro',
	lazy => 1,
	default => sub {
		Data::Partial::Google::Parser->parse(shift->rule)
	},
);

# Allow Data::Partial::Google->new("a,b(c/d)")
sub BUILDARGS {
	my ($class, @args) = @_;
	unshift @args, "rule" if @args % 2;
	return { @args };
}

sub has_rule {
	my ($self) = @_;
	my $rule = $self->rule;
	return defined $rule && length $rule;
}

sub BUILD {
	my ($self) = @_;
	$self->filter if $self->has_rule;
}

sub mask {
	my ($self, $obj) = @_;
	if ($self->has_rule) {
		return $self->filter->mask($obj);
	} else {
		return $obj;
	}
}

1;

=head1 SYNOPSIS

    my $data = {
        artist => "Alice In Chains",
        title  => "Sap",
        year   => 1992,
        tracks => [
            { title => "Brother",      length => "4:27" },
            { title => "Got Me Wrong", length => "4:12" },
            { title => "Right Turn",   length => "3:17" },
            { title => "Am I Inside",  length => "5:09" },
        ]
    };

    my $filter = Data::Partial::Google->new('artist,title,tracks/title');
    my $filtered = $filter->mask($data);

    cmp_deeply($data, {
        artist => "Alice In Chains",
        title  => "Sap",
        tracks => [
            { title => "Brother" },
            { title => "Got Me Wrong" },
            { title => "Right Turn" },
            { title => "Am I Inside" },
        ]
    });

    # ok 1

=head1 DESCRIPTION

This module filters data structures without changing their shape, making
it easy to expose only the parts of interest to a consumer. It aims to be
compatible with Google's implementation of partial responses using the C<fields>
parameter, and it is based on the node module "json-mask".

=head1 RULES

=head2 Properties

Select one or more properties from an object by seprating them with commas:

    foo,bar,baz

=head2 Descendants

Use the slash operator to select properties within properties:

   foo/bar/baz

will return the 'baz' property of the 'bar' property of the 'foo' property.

Arrays are handled transparently: if 'foo' is an array, then the rule
'bar/baz' will be applied to every entry in 'foo'.

=head2 Sub-selection

Use the parentheses to select specific properties from inside another:

    foo(bar,baz)

selects the 'bar' and 'baz' properties from 'foo' (or from each element in
'foo').

=head2 Wildcards

Use the asterisk to select all sub-properties of a property:

    foo/*/baz

selects the 'baz' property from every property of 'foo' that has a 'baz'.

=head1 METHODS

=head2 mask

C<< $filter->mask($data) >> returns C<$data>, as modified by C<$filter>'s rules.
In most senses the returned value will be a deep copy of C<$data>, as hashes
and arrays will have been reconstructed, but other values, such as code
references and glob references, will be copied directly, so be cautious.

=head1 SEE ALSO

=over 4

=item *

Google Partial Responses: L<https://developers.google.com/discovery/v1/performance#partial-response>

=item *

json-mask: L<https://github.com/nemtsov/json-mask>

=back

About

Filter data structures for "partial responses," Google style

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

 
 
 

Contributors 4

  •  
  •  
  •  
  •  

Languages