APISchema
view release on metacpan or search on metacpan
Revision history for Perl extension APISchema
1.37 2018-02-08T10:31:50Z
- Allow `example: undef` and serve document
1.36 2017-12-25T12:45:24Z
- show enum values in type column
1.35 2017-12-13T14:30:28Z
- MockServer serves default status codes in definitions
1.34 2017-11-30T16:29:26Z
- Define prototype of type before calling it
1.33 2017-11-30T14:39:09Z
- Resolve anyOf, allOf and oneOf keywords when serving Mock Server and API Document
1.32 2017-11-30T06:08:51Z
- MockServer always returns bytes
lib/APISchema/Generator/Markdown.pm view on Meta::CPAN
$renderer,
$routes,
$resources,
),
join('', map {
my $route = $_;
my $req = resolve_encoding($route->request_resource);
my $request_resource = $route->canonical_request_resource($root);
my $codes = $route->responsible_codes;
my $default_code = $route->default_responsible_code;
my $response_resource = $route->canonical_response_resource($root, [
$default_code
]);
my $res = $_->response_resource;
$res = $_->responsible_code_is_specified
? { map { $_ => resolve_encoding($res->{$_}) } @$codes }
: { '' => resolve_encoding($res) };
$self->{route}->(
$renderer,
$route,
lib/APISchema/Generator/Markdown.pm view on Meta::CPAN
$renderer,
$route,
APISchema::Generator::Markdown::ExampleFormatter->new(
resolver => $resolver,
spec => $request_resource,
),
),
res => $self->{response_example}->(
$renderer,
$route,
$default_code,
APISchema::Generator::Markdown::ExampleFormatter->new(
resolver => $resolver,
spec => $response_resource,
),
),
},
{
req => $self->{request}->($renderer, $route, $req),
res => join("\n", map {
$self->{response}->($renderer, $route, $_, $res->{$_});
lib/APISchema/Generator/Markdown.pm view on Meta::CPAN
?= $resource->definition->{description} || ''
#### Properties
? if (scalar @$properties) {
|Property|Type|Default|Example|Restrictions|Description|
|--------|----|-------|-------|------------|-----------|
? for my $prop (@$properties) {
? my $def = $prop->{definition};
|`<?= $prop->{path} ?>` |<?= type($def) ?> |<?= code($def->{default}) ?> |<?= code($def->{example}, exists $def->{example}) ?> |<?= restriction($def) ?> |<?= desc($def->{description}) ?> |
? } # $prop
? } # scalar @$properties
lib/APISchema/Generator/Markdown/ResourceResolver.pm view on Meta::CPAN
$ref = $ref =~ s/^#//r;
my $def = JSON::Pointer->get($self->schema, $ref);
return ($self->_collect_example($path, $def), 1) if $def;
}
my %result;
my $type = $definition->{type} || '';
_foreach_properties($path, $definition, sub {
my ($example, $exists) = $self->_collect_example(@_);
unless ($exists) {
if (exists $_[1]->{default}) {
$example = $_[1]->{default};
$exists = 1;
}
}
$result{$_[0]->[-1]} = $example if $exists;
});
return (\%result, 1) if $type eq 'object';
if ($type eq 'array') {
return ([ $result{'[]'} ], 1) if $result{'[]'};
lib/APISchema/Route.pm view on Meta::CPAN
sub responsible_codes {
my ($self) = @_;
return [200] unless $self->responsible_code_is_specified;
my $res = $self->response_resource;
my @codes = sort grep { $_ =~ qr!\A[0-9]+\z! } keys %$res;
return @codes ? [@codes] : [200];
}
sub default_responsible_code {
my ($self) = @_;
$self->responsible_codes->[0];
}
1;
lib/Plack/App/APISchema/MockServer.pm view on Meta::CPAN
my ($matched, $router_simple_route) = $self->router->routematch($env);
unless ($matched) {
return [404, ['Content-Type' => 'text/plain; charset=utf-8'], ['not found']];
}
my $root = $self->schema->get_resource_root;
my $route = $self->schema->get_route_by_name($router_simple_route->name);
my $default_code = $route->default_responsible_code;
my $response_resource = $route->canonical_response_resource($root, [
$default_code
]);
my $resolver = APISchema::Generator::Markdown::ResourceResolver->new(schema => $root);
my $formatter = APISchema::Generator::Markdown::ExampleFormatter->new(
resolver => $resolver,
spec => $response_resource,
);
# TODO: serve all headers defined in example
# TODO: format body with encoding
return [$default_code, ['Content-Type' => 'application/json; charset=utf-8'], [encode_utf8($formatter->body)]];
}
sub router {
my ($self) = @_;
return $self->{router} if $self->{router};
my $generator = APISchema::Generator::Router::Simple->new;
$self->{router} = $generator->generate_router($self->schema);
}
t/APISchema-Route.t view on Meta::CPAN
description => 'This API calculates your BMI.',
destination => {
controller => 'BMI',
action => 'calculate',
},
method => 'POST',
request_resource => 'health',
response_resource => 'bmi',
);
cmp_deeply $route->responsible_codes, [200];
is $route->default_responsible_code, 200;
ok ! $route->responsible_code_is_specified;
};
subtest 'when multiple response codes are specified' => sub {
my $route = APISchema::Route->new(
route => '/bmi/',
title => 'BMI API',
description => 'This API calculates your BMI.',
destination => {
controller => 'BMI',
action => 'calculate',
},
method => 'POST',
request_resource => 'health',
response_resource => {
201 => 'bmi',
401 => 'bmi',
400 => 'bmi',
},
);
is $route->default_responsible_code, 201;
ok $route->responsible_code_is_specified;
};
}
( run in 1.220 second using v1.01-cache-2.11-cpan-0a6323c29d9 )