Bug 19410: Add Koha::Objects->search_for_api

Following the discussion about the best way to make things simpler for
developing the REST api, I quote Lari's email:

"As many other endpoint will have the exact same usage, by looking at your example, I would prefer to avoid writing parameter / pagination / sorting / header handling for each list operation in our API controllers. Do you think it's possible to centralize all of this e.g. by passing $c into a customized search sub? Perhaps in Koha::Objects?
so instead we could have something like (ignore my bad choice of naming)...:
sub list_vendors {
  my $c = shift->openapi->valid_input or return;
  my $args = $c->validation->output;
  my $vendors;

  return try {
    $vendors = Koha::Acquisition::Booksellers->api_list_search($c);
    return $c->render(status => 200, openapi => $vendors);
  } catch {
    ...
  }
}"

We all agreed we neeed something like that. Here's a possible implementation. I take
advantage of the previously written Mojo helpers, that are fully covered by tests.

I submit this early so anyone can take a look and gather ideas to make it even better.
I'm already using it (effectively) for the /acquisitions/orders endpoint I'm writing
on bug 18731.

Thanks!

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>

Signed-off-by: Lari Taskula <lari.taskula@jns.fi>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Tomás Cohen Arazi 2017-10-04 15:41:35 -03:00 committed by Jonathan Druart
parent 8430a541af
commit 7805ef2c01

View file

@ -23,6 +23,7 @@ use Carp;
use List::MoreUtils qw( none );
use Koha::Database;
use Koha::Exceptions;
=head1 NAME
@ -170,6 +171,88 @@ sub search_related {
}
}
=head3 search_for_api
my @objects = Koha::Objects->earch_for_api( $c );
Searches for objects given a controller object I<$c>.
=cut
sub search_for_api {
my ( $self, $c ) = @_;
my $args = $c->validation->output;
my $attributes;
# Extract reserved params
my ( $filtered_params, $reserved_params ) = $c->extract_reserved_params($args);
# Merge sorting into query attributes
$c->dbic_merge_sorting(
{
attributes => $attributes,
params => $reserved_params
}
);
# Merge pagination into query attributes
$c->dbic_merge_pagination(
{
attributes => $attributes,
params => $reserved_params
}
);
# Perform search
my $objects = $self->search( $filtered_params, $attributes );
$c->add_pagination_headers({ total => $objects->count, params => $args })
if $objects->is_paged;
return $objects;
}
=head2 _build_query_params_from_api
my $params = _build_query_params_from_api( $filtered_params, $reserved_params );
Builds the params for searching on DBIC based on the selected matching algorithm.
Valid options are I<contains>, I<starts_with>, I<ends_with> and I<exact>. Default is
I<contains>. If other value is passed, a Koha::Exceptions::WrongParameter exception
is raised.
=cut
sub _build_query_params_from_api {
my ( $filtered_params, $reserved_params ) = @_;
my $params;
my $match = $reserved_params->{_match} // 'contains';
foreach my $param ( keys %{$filtered_params} ) {
if ( $match eq 'contains' ) {
$params->{$param} =
{ like => '%' . $filtered_params->{$param} . '%' };
}
elsif ( $match eq 'starts_with' ) {
$params->{$param} = { like => $filtered_params->{$param} . '%' };
}
elsif ( $match eq 'ends_with' ) {
$params->{$param} = { like => '%' . $filtered_params->{$param} };
}
elsif ( $match eq 'exact' ) {
$params->{$param} = $filtered_params->{$param};
}
else {
Koha::Exceptions::WrongParameter->throw(
"Invalid value for _match param ($match)");
}
}
return $params;
}
=head3 single
my $object = Koha::Objects->search({}, { rows => 1 })->single