Skip to content

Commit 9e21623

Browse files
authored
Merge pull request #1204 from metacpan/haarg/no-join
remove join parameter
2 parents b51192a + ab05bf2 commit 9e21623

File tree

7 files changed

+33
-310
lines changed

7 files changed

+33
-310
lines changed

docs/API-docs.md

Lines changed: 28 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ Part of being polite is letting us know who you are and how to reach you. This
2727
Available fields can be found by accessing the corresponding `_mapping` endpoint.
2828

2929

30-
* [/author/_mapping](https://fastapi.metacpan.org/v1/author/_mapping) - [explore](https://explorer.metacpan.org/?url=/author/_mapping)
31-
* [/distribution/_mapping](https://fastapi.metacpan.org/v1/distribution/_mapping) - [explore](https://explorer.metacpan.org/?url=/distribution/_mapping)
32-
* [/favorite/_mapping](https://fastapi.metacpan.org/v1/favorite/_mapping) - [explore](https://explorer.metacpan.org/?url=/favorite/_mapping)
33-
* [/file/_mapping](https://fastapi.metacpan.org/v1/file/_mapping) - [explore](https://explorer.metacpan.org/?url=/file/_mapping)
34-
* [/module/_mapping](https://fastapi.metacpan.org/v1/module/_mapping) - [explore](https://explorer.metacpan.org/?url=/module/_mapping)
35-
* [/rating/_mapping](https://fastapi.metacpan.org/v1/rating/_mapping) - [explore](https://explorer.metacpan.org/?url=/rating/_mapping)
36-
* [/release/_mapping](https://fastapi.metacpan.org/v1/release/_mapping) - [explore](https://explorer.metacpan.org/?url=/release/_mapping)
30+
* [`/author/_mapping`](https://fastapi.metacpan.org/v1/author/_mapping) - [explore](https://explorer.metacpan.org/?url=/author/_mapping)
31+
* [`/distribution/_mapping`](https://fastapi.metacpan.org/v1/distribution/_mapping) - [explore](https://explorer.metacpan.org/?url=/distribution/_mapping)
32+
* [`/favorite/_mapping`](https://fastapi.metacpan.org/v1/favorite/_mapping) - [explore](https://explorer.metacpan.org/?url=/favorite/_mapping)
33+
* [`/file/_mapping`](https://fastapi.metacpan.org/v1/file/_mapping) - [explore](https://explorer.metacpan.org/?url=/file/_mapping)
34+
* [`/module/_mapping`](https://fastapi.metacpan.org/v1/module/_mapping) - [explore](https://explorer.metacpan.org/?url=/module/_mapping)
35+
* [`/rating/_mapping`](https://fastapi.metacpan.org/v1/rating/_mapping) - [explore](https://explorer.metacpan.org/?url=/rating/_mapping)
36+
* [`/release/_mapping`](https://fastapi.metacpan.org/v1/release/_mapping) - [explore](https://explorer.metacpan.org/?url=/release/_mapping)
3737

3838

3939
## Field documentation
@@ -44,42 +44,12 @@ Fields are documented in the API codebase: https://github.com/metacpan/metacpan-
4444

4545
Performing a search without any constraints is an easy way to get sample data
4646

47-
* [/author/_search](https://fastapi.metacpan.org/v1/author/_search)
48-
* [/distribution/_search](https://fastapi.metacpan.org/v1/distribution/_search)
49-
* [/favorite/_search](https://fastapi.metacpan.org/v1/favorite/_search)
50-
* [/file/_search](https://fastapi.metacpan.org/v1/file/_search)
51-
* [/rating/_search](https://fastapi.metacpan.org/v1/rating/_search)
52-
* [/release/_search](https://fastapi.metacpan.org/v1/release/_search)
53-
54-
## Joins
55-
56-
ElasticSearch itself doesn't support joining data across multiple types. The API server can, however, handle a `join` query parameter if the underlying type was set up accordingly. Browse https://github.com/metacpan/metacpan-api/blob/master/lib/MetaCPAN/Server/Controller/ to see all join conditions. Here are some examples.
57-
58-
Joins on documents:
59-
60-
* [/author/PERLER?join=favorite](https://fastapi.metacpan.org/v1/author/PERLER?join=favorite)
61-
* [/author/PERLER?join=favorite&join=release](https://fastapi.metacpan.org/v1/author/PERLER?join=favorite&join=release)
62-
* [/release/Moose?join=author](https://fastapi.metacpan.org/v1/release/Moose?join=author)
63-
* [/module/Moose?join=release](https://fastapi.metacpan.org/v1/module/Moose?join=release)
64-
65-
Joins on search results is work in progress.
66-
67-
Restricting the joined results can be done by using the [boolean "should"](https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-bool-query.html) occurrence type:
68-
69-
```sh
70-
curl -XPOST https://fastapi.metacpan.org/v1/author/PERLER?join=release -d '
71-
{
72-
"query": {
73-
"bool": {
74-
"should": [{
75-
"term": {
76-
"release.status": "latest"
77-
}
78-
}]
79-
}
80-
}
81-
}'
82-
```
47+
* [`/author/_search`](https://fastapi.metacpan.org/v1/author/_search)
48+
* [`/distribution/_search`](https://fastapi.metacpan.org/v1/distribution/_search)
49+
* [`/favorite/_search`](https://fastapi.metacpan.org/v1/favorite/_search)
50+
* [`/file/_search`](https://fastapi.metacpan.org/v1/file/_search)
51+
* [`/rating/_search`](https://fastapi.metacpan.org/v1/rating/_search)
52+
* [`/release/_search`](https://fastapi.metacpan.org/v1/release/_search)
8353

8454
## JSONP
8555

@@ -101,33 +71,33 @@ The `/download_url` endpoint exists specifically for the `cpanm` client. It tak
10171

10272
Obviously anyone can use this endpoint, but we'll only consider changes to this endpoint after considering how `cpanm` might be affected.
10373

104-
* [https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny](https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny)
105-
* [https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01](https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01)
106-
* [https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01](https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01)
107-
* [https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02](https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02)
108-
* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24)
109-
* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1)
110-
* [https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1)
74+
* [`https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny`](https://fastapi.metacpan.org/v1/download_url/HTTP::Tiny)
75+
* [`https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01`](https://fastapi.metacpan.org/v1/download_url/Moose?version===0.01)
76+
* [`https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01`](https://fastapi.metacpan.org/v1/download_url/Moose?version=!=0.01)
77+
* [`https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02`](https://fastapi.metacpan.org/v1/download_url/Moose?version=<=0.02)
78+
* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.24)
79+
* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27&dev=1)
80+
* [`https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1`](https://fastapi.metacpan.org/v1/download_url/Try::Tiny?version=>0.21,<0.27,!=0.26&dev=1)
11181

11282
### `/release/{distribution}`
11383

11484
### `/release/{author}/{release}`
11585

116-
The `/release` endpoint accepts either the name of a `distribution` (e.g. [/release/Moose](https://fastapi.metacpan.org/v1/release/Moose)), which returns the most recent release of the distribution. Or provide the full path which consists of its `author` and the name of the `release` (e.g. [/release/DOY/Moose-2.0001](https://fastapi.metacpan.org/v1/release/DOY/Moose-2.0001)).
86+
The `/release` endpoint accepts either the name of a `distribution` (e.g. [`/release/Moose`](https://fastapi.metacpan.org/v1/release/Moose)), which returns the most recent release of the distribution. Or provide the full path which consists of its `author` and the name of the `release` (e.g. [`/release/DOY/Moose-2.0001`](https://fastapi.metacpan.org/v1/release/DOY/Moose-2.0001)).
11787

11888
### `/author/{author}`
11989

120-
`author` refers to the pauseid of the author. It must be uppercased (e.g. [/author/DOY](https://fastapi.metacpan.org/v1/author/DOY)).
90+
`author` refers to the pauseid of the author. It must be uppercased (e.g. [`/author/DOY`](https://fastapi.metacpan.org/v1/author/DOY)).
12191

12292
### `/module/{module}`
12393

124-
Returns the corresponding `file` of the latest version of the `module`. Considering that Moose-2.0001 is the latest release, the result of [/module/Moose](https://fastapi.metacpan.org/v1/module/Moose) is the same as [/file/DOY/Moose-2.0001/lib/Moose.pm](https://fastapi.metacpan.org/v1/file/DOY/Moose-2.0001/lib/Moose.pm).
94+
Returns the corresponding `file` of the latest version of the `module`. Considering that Moose-2.0001 is the latest release, the result of [`/module/Moose`](https://fastapi.metacpan.org/v1/module/Moose) is the same as [`/file/DOY/Moose-2.0001/lib/Moose.pm`](https://fastapi.metacpan.org/v1/file/DOY/Moose-2.0001/lib/Moose.pm).
12595

12696
### `/pod/{module}`
12797

12898
### `/pod/{author}/{release}/{path}`
12999

130-
Returns the POD of the given module. You can change the output format by either passing a `content-type` query parameter (e.g. [/pod/Moose?content-type=text/plain](https://fastapi.metacpan.org/v1/pod/Moose?content-type=text/plain) or by adding an `Accept` header to the HTTP request. Valid content types are:
100+
Returns the POD of the given module. You can change the output format by either passing a `content-type` query parameter (e.g. [`/pod/Moose?content-type=text/plain`](https://fastapi.metacpan.org/v1/pod/Moose?content-type=text/plain) or by adding an `Accept` header to the HTTP request. Valid content types are:
131101

132102
* text/html (default)
133103
* text/plain
@@ -143,11 +113,11 @@ Returns the full source of the latest, authorized version of the given
143113

144114
Names of latest releases by OALDERS:
145115

146-
https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100
116+
[`https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100`](https://fastapi.metacpan.org/v1/release/_search?q=author:OALDERS%20AND%20status:latest&fields=name,status&size=100)
147117

148118
5,000 CPAN Authors:
149119

150-
[https://fastapi.metacpan.org/v1/author/_search?q=*&size=5000](https://fastapi.metacpan.org/author/_search?q=*)
120+
[`https://fastapi.metacpan.org/v1/author/_search?q=*&size=5000`](https://fastapi.metacpan.org/author/_search?q=*)
151121

152122
All CPAN Authors Who Have Provided Twitter IDs:
153123

@@ -159,11 +129,11 @@ https://fastapi.metacpan.org/v1/author/_search?q=updated:*&sort=updated:desc
159129

160130
First 100 distributions which SZABGAB has given a ++:
161131

162-
https://fastapi.metacpan.org/v1/favorite/_search?q=user:sWuxlxYeQBKoCQe1f-FQ_Q&size=100&fields=distribution
132+
https://fastapi.metacpan.org/v1/favorite/_search?q=user:sWuxlxYeQBKoCQe1f-FQ_Q&size=100&fields=distribution
163133

164134
The 100 most recent releases ( similar to https://metacpan.org/recent )
165135

166-
https://fastapi.metacpan.org/v1/release/_search?q=status:latest&fields=name,status,date&sort=date:desc&size=100
136+
https://fastapi.metacpan.org/v1/release/_search?q=status:latest&fields=name,status,date&sort=date:desc&size=100
167137

168138
Number of ++'es that DOY's dists have received:
169139

lib/MetaCPAN/Server/Controller.pm

Lines changed: 0 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@ has type => (
2626
default => sub { shift->action_namespace },
2727
);
2828

29-
has relationships => (
30-
is => 'ro',
31-
isa => HashRef,
32-
default => sub { {} },
33-
traits => ['Hash'],
34-
handles => { has_relationships => 'count' },
35-
);
36-
3729
my $MAX_SIZE = 5000;
3830

3931
# apply "filters" like \&model but for fabricated data
@@ -128,90 +120,6 @@ sub search : Path('_search') : ActionClass('~Deserialize') {
128120
} or do { $self->internal_error( $c, $@ ) };
129121
}
130122

131-
sub join : ActionClass('~Deserialize') {
132-
my ( $self, $c ) = @_;
133-
my $joins = $self->relationships;
134-
my @req_joins = $c->req->param('join');
135-
my $is_get = ref $c->stash->{hits} ? 0 : 1;
136-
my $query
137-
= $c->req->params->{q}
138-
? { query => { query_string => { query => $c->req->params->{q} } } }
139-
: $c->req->data ? $c->req->data
140-
: { query => { match_all => {} } };
141-
$c->detach(
142-
'/not_allowed',
143-
[
144-
'unknown join type, valid values are '
145-
. Moose::Util::english_list( keys %$joins )
146-
]
147-
) if ( scalar grep { !$joins->{$_} } @req_joins );
148-
149-
while ( my ( $join, $config ) = each %$joins ) {
150-
my $has_many = ref $config->{type};
151-
my ($type) = $has_many ? @{ $config->{type} } : $config->{type};
152-
my $cself = $config->{self} || $join;
153-
next unless ( grep { $_ eq $join } @req_joins );
154-
my $data
155-
= $is_get
156-
? [ $c->stash ]
157-
: [
158-
map {
159-
$_->{_source}
160-
|| single_valued_arrayref_to_scalar( $_->{fields} )
161-
} @{ $c->stash->{hits}->{hits} }
162-
];
163-
my @ids = List::AllUtils::uniq grep {defined}
164-
map { ref $cself eq 'CODE' ? $cself->($_) : $_->{$cself} } @$data;
165-
my $filter = { terms => { $config->{foreign} => [@ids] } };
166-
my $filtered = {%$query}; # don't work on $query
167-
$filtered->{filter}
168-
= $query->{filter}
169-
? { and => [ $filter, $query->{filter} ] }
170-
: $filter;
171-
my $foreign = eval {
172-
$c->model("CPAN::$type")->query( $filtered->{query} )
173-
->filter( $filtered->{filter} )->size(1000)->raw->all;
174-
} or do { $self->internal_error( $c, $@ ) };
175-
$c->detach(
176-
"/not_allowed",
177-
[
178-
'The number of joined documents exceeded the allowed number of 1000 documents by '
179-
. ( $foreign->{hits}->{total} - 1000 )
180-
. '. Please reduce the number of documents or apply additional filters.'
181-
]
182-
) if ( $foreign->{hits}->{total} > 1000 );
183-
$c->stash->{took} += $foreign->{took} unless ($is_get);
184-
185-
if ($has_many) {
186-
my $many;
187-
for ( @{ $foreign->{hits}->{hits} } ) {
188-
my $list = $many->{ $_->{_source}->{ $config->{foreign} } }
189-
||= [];
190-
push( @$list, $_ );
191-
}
192-
$foreign = $many;
193-
}
194-
else {
195-
$foreign = { map { $_->{_source}->{ $config->{foreign} } => $_ }
196-
@{ $foreign->{hits}->{hits} } };
197-
}
198-
for (@$data) {
199-
my $key = ref $cself eq 'CODE' ? $cself->($_) : $_->{$cself};
200-
next unless ($key);
201-
my $result = $foreign->{$key};
202-
$_->{$join}
203-
= $has_many
204-
? {
205-
hits => {
206-
hits => $result,
207-
total => scalar @{ $result || [] }
208-
}
209-
}
210-
: $result;
211-
}
212-
}
213-
}
214-
215123
sub not_found : Private {
216124
my ( $self, $c ) = @_;
217125
$c->cdn_never_cache(1);
@@ -238,57 +146,8 @@ sub internal_error {
238146

239147
sub end : Private {
240148
my ( $self, $c ) = @_;
241-
$c->forward('join')
242-
if ( $self->has_relationships && $c->req->param('join') );
243149
$c->forward('/end');
244150
}
245151

246152
__PACKAGE__->meta->make_immutable;
247153
1;
248-
249-
__END__
250-
251-
=head1 ATTRIBUTES
252-
253-
=head2 relationships
254-
255-
MetaCPAN::Server::Controller::Author->config(
256-
relationships => {
257-
release => {
258-
type => ['Release'],
259-
self => 'pauseid',
260-
foreign => 'author',
261-
}
262-
}
263-
);
264-
265-
Contains a HashRef of relationships with other controllers.
266-
If C<type> is an ArrayRef, the relationship is considered a
267-
I<has many> relationship.
268-
269-
Unless a C<self> exists, the name of the relationship is used
270-
as key to join on. C<self> can also be a CodeRef, if the foreign
271-
key is build from several local keys. In this case, again the name of
272-
the relationship is used as key in the result.
273-
274-
C<foreign> refers to the foreign key on the C<type> controller the data
275-
is joined with.
276-
277-
=head1 ACTIONS
278-
279-
=head2 join
280-
281-
This action is called if the controller has L</relationships> defined
282-
and if one or more C<join> query parameters are defined. It then
283-
does a I<left join> based on the information provided by
284-
L</relationships>.
285-
286-
This works both for GET requests, where only one document is requested
287-
and search requests, where a number of documents is returned.
288-
It also passes through search data (either the C<q> query string or
289-
the request body).
290-
291-
B<The number of documents that can be joined is limited to 1000 per
292-
relationship for now.>
293-
294-
=cut

lib/MetaCPAN/Server/Controller/Author.pm

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,6 @@ BEGIN { extends 'MetaCPAN::Server::Controller' }
1010

1111
with 'MetaCPAN::Server::Role::JSONP';
1212

13-
__PACKAGE__->config(
14-
relationships => {
15-
release => {
16-
type => ['Release'],
17-
self => 'pauseid',
18-
foreign => 'author',
19-
},
20-
favorite => {
21-
type => ['Favorite'],
22-
self => 'user',
23-
foreign => 'user',
24-
}
25-
}
26-
);
27-
2813
# https://fastapi.metacpan.org/v1/author/LLAP
2914
sub get : Path('') : Args(1) {
3015
my ( $self, $c, $id ) = @_;

lib/MetaCPAN/Server/Controller/Changes.pm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ BEGIN { extends 'MetaCPAN::Server::Controller' }
1212

1313
with 'MetaCPAN::Server::Role::JSONP';
1414

15-
# TODO: __PACKAGE__->config(relationships => ?)
16-
1715
has '+type' => ( default => 'file' );
1816

1917
sub index : Chained('/') : PathPart('changes') : CaptureArgs(0) {

lib/MetaCPAN/Server/Controller/File.pm

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,6 @@ BEGIN { extends 'MetaCPAN::Server::Controller' }
1111

1212
with 'MetaCPAN::Server::Role::JSONP';
1313

14-
__PACKAGE__->config(
15-
relationships => {
16-
author => {
17-
type => 'Author',
18-
foreign => 'pauseid',
19-
},
20-
release => {
21-
type => 'Release',
22-
self => sub {
23-
ElasticSearchX::Model::Util::digest( $_[0]->{author},
24-
$_[0]->{release} );
25-
},
26-
foreign => 'id',
27-
}
28-
}
29-
);
30-
3114
sub find : Path('') {
3215
my ( $self, $c, $author, $release, @path ) = @_;
3316

lib/MetaCPAN/Server/Controller/Release.pm

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ BEGIN { extends 'MetaCPAN::Server::Controller' }
1010

1111
with 'MetaCPAN::Server::Role::JSONP';
1212

13-
__PACKAGE__->config(
14-
relationships => {
15-
author => {
16-
type => 'Author',
17-
foreign => 'pauseid',
18-
}
19-
}
20-
);
21-
2213
sub find : Path('') : Args(1) {
2314
my ( $self, $c, $name ) = @_;
2415
my $file = $self->model($c)->find($name);

0 commit comments

Comments
 (0)