APISchema

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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 )