mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-08 11:23:58 +00:00
Documentation and automatic documentation
- added POD to Role.pm - added README.md files translated from Role.pm POD - added an autodoc script (based on AutoDoc.pm role). The script prints a listing of the methods built in Role.pm - added class_documentation() and method_documentation() accessors on all object and API classes which return the documentation supplied in the Swagger spec for the API
This commit is contained in:
parent
49034946a0
commit
c06af6d141
@ -100,6 +100,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Object/BaseObject.pm"));
|
||||
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm"));
|
||||
supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm"));
|
||||
supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/WWW/" + moduleName + "/Role").replace('/', File.separatorChar), "AutoDoc.pm"));
|
||||
supportingFiles.add(new SupportingFile("autodoc.script.mustache", ("bin/").replace('/', File.separatorChar), "autodoc"));
|
||||
}
|
||||
|
||||
public CodegenType getTag() {
|
||||
|
156
modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
Normal file
156
modules/swagger-codegen/src/main/resources/perl/AutoDoc.mustache
Normal file
@ -0,0 +1,156 @@
|
||||
package WWW::{{moduleName}}::Role::AutoDoc;
|
||||
use List::MoreUtils qw(uniq);
|
||||
|
||||
use Moose::Role;
|
||||
|
||||
sub autodoc {
|
||||
my $self = shift;
|
||||
|
||||
$self->_printisa;
|
||||
$self->_printmethods;
|
||||
$self->_printattrs;
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub _printisa {
|
||||
my $self = shift;
|
||||
my $meta = $self->meta;
|
||||
|
||||
my $myclass = ref $self;
|
||||
|
||||
my $super = join ', ', $meta->superclasses;
|
||||
my @roles = $meta->calculate_all_roles;
|
||||
shift(@roles); # the first is a composite, the rest are the roles
|
||||
|
||||
my $isa = join ', ', $meta->linearized_isa;
|
||||
my $sub = join ', ', $meta->subclasses;
|
||||
my $dsub = join ', ', $meta->direct_subclasses;
|
||||
|
||||
my ($rolepkg, $role_reqs);
|
||||
|
||||
$~ = 'INHERIT';
|
||||
write;
|
||||
|
||||
foreach my $role (@roles) {
|
||||
$rolepkg = $role->{package};
|
||||
$role_reqs = join ', ', keys %{$role->{required_methods}};
|
||||
$~ = 'ROLES';
|
||||
write;
|
||||
}
|
||||
|
||||
# ----- format specs -----
|
||||
format INHERIT =
|
||||
|
||||
@* -
|
||||
$myclass
|
||||
ISA: @*
|
||||
$isa
|
||||
Direct subclasses: @*
|
||||
$dsub
|
||||
All subclasses: @*
|
||||
$sub
|
||||
.
|
||||
format ROLES =
|
||||
Composes: @*
|
||||
$rolepkg
|
||||
requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
|
||||
$role_reqs
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
sub _printmethods {
|
||||
my $self = shift;
|
||||
$~ = 'METHODHEAD';
|
||||
write;
|
||||
$self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names;
|
||||
}
|
||||
|
||||
sub _printmethod {
|
||||
my ($self, $methodname) = @_;
|
||||
return if $methodname =~ /^_/;
|
||||
return if $self->meta->has_attribute($methodname);
|
||||
my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY
|
||||
DOES isa BUILDALL does VERSION dump
|
||||
);
|
||||
return if $internal{$methodname};
|
||||
my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose
|
||||
|
||||
return if $method->original_package_name eq __PACKAGE__;
|
||||
|
||||
my $delegation = '';
|
||||
my $delegate_to = '';
|
||||
my $via = '';
|
||||
my $on = '';
|
||||
if ($method->can('associated_attribute')) {
|
||||
$delegate_to = $method->delegate_to_method;
|
||||
my $aa = $method->associated_attribute;
|
||||
$on = $aa->{isa};
|
||||
$via = $aa->{name};
|
||||
}
|
||||
|
||||
$~ = 'METHOD';
|
||||
write;
|
||||
|
||||
# ----- format specs -----
|
||||
format METHODHEAD =
|
||||
|
||||
METHODS
|
||||
-------
|
||||
Name delegate to on via
|
||||
===================================================================================================================================
|
||||
.
|
||||
format METHOD =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<...
|
||||
$methodname, $delegate_to, $on, $via
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
sub _printattrs {
|
||||
my $self = shift;
|
||||
$~ = 'ATTRHEAD';
|
||||
write;
|
||||
$self->_printattr($_) for sort $self->meta->get_attribute_list;
|
||||
}
|
||||
|
||||
sub _printattr {
|
||||
my ($self, $attrname) = @_;
|
||||
return if $attrname =~ /^_/;
|
||||
my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname";
|
||||
|
||||
my $is;
|
||||
$is = 'rw' if $attr->get_read_method && $attr->get_write_method;
|
||||
$is = 'ro' if $attr->get_read_method && ! $attr->get_write_method;
|
||||
$is = 'wo' if $attr->get_write_method && ! $attr->get_read_method;
|
||||
$is = '--' if ! $attr->get_write_method && ! $attr->get_read_method;
|
||||
$is or die "No \$is for $attrname";
|
||||
|
||||
my $tc = $attr->type_constraint || '';
|
||||
my $from = $attr->associated_class->name || '';
|
||||
my $reqd = $attr->is_required ? 'reqd' : 'opt';
|
||||
my $lazy = $attr->is_lazy ? 'lazy' : '';
|
||||
my $doc = $attr->has_documentation ? 'yes' : '';
|
||||
my $handles = join ', ', sort @{$attr->handles || []};
|
||||
|
||||
$~ = 'ATTR';
|
||||
write;
|
||||
|
||||
# ----- format specs -----
|
||||
format ATTRHEAD =
|
||||
|
||||
ATTRIBUTES
|
||||
----------
|
||||
Name is isa reqd lazy doc handles
|
||||
==============================================================================================================
|
||||
.
|
||||
format ATTR =
|
||||
@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$attrname, $is, $tc, $reqd, $lazy, $doc, $handles
|
||||
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
|
||||
$handles
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
1;
|
164
modules/swagger-codegen/src/main/resources/perl/README.md
Normal file
164
modules/swagger-codegen/src/main/resources/perl/README.md
Normal file
@ -0,0 +1,164 @@
|
||||
# NAME
|
||||
|
||||
WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project
|
||||
|
||||
## A note on Moose
|
||||
|
||||
This role is the only component of the library that uses Moose. See
|
||||
WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
The Perl Swagger Codegen project builds a library of Perl modules to interact with
|
||||
a web service defined by a Swagger specification. See below for how to build the
|
||||
library.
|
||||
|
||||
This module provides an interface to the generated library. All the classes,
|
||||
objects, and methods (well, not quite \*all\*, see below) are flattened into this
|
||||
role.
|
||||
|
||||
package MyApp;
|
||||
use Moose;
|
||||
has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' );
|
||||
with 'WWW::{{moduleName}}::Role';
|
||||
sub auth_setup_handler {...}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyApp->new({username => $username, password => $password});
|
||||
|
||||
my $pet = $api->get_pet_by_id(pet_id => $pet_id);
|
||||
|
||||
|
||||
Notice that you need to provide the code to accept the parameters passed in to `new()`
|
||||
(by setting up attributes via the `has` keyword). They should be used by
|
||||
`auth_setup_handler()` to configure authentication (see below).
|
||||
|
||||
## Structure of the library
|
||||
|
||||
The library consists of a set of API classes, one for each endpoint. These APIs
|
||||
implement the method calls available on each endpoint.
|
||||
|
||||
Additionally, there is a set of "object" classes, which represent the objects
|
||||
returned by and sent to the methods on the endpoints.
|
||||
|
||||
An API factory class is provided, which builds instances of each endpoint API.
|
||||
|
||||
This Moose role flattens all the methods from the endpoint APIs onto the consuming
|
||||
class. It also provides methods to retrieve the endpoint API objects, and the API
|
||||
factory object, should you need it.
|
||||
|
||||
For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
|
||||
|
||||
# METHODS
|
||||
|
||||
## `auth_setup_handler()`
|
||||
|
||||
This method is NOT provided - you must write it yourself. Its task is to configure
|
||||
authentication for each request.
|
||||
|
||||
The method is called on your `$api` object and passed the following parameters:
|
||||
|
||||
- `header_params`
|
||||
|
||||
A hashref that will become the request headers. You can insert auth
|
||||
parameters.
|
||||
|
||||
- `query_params`
|
||||
|
||||
A hashref that will be encoded into the request URL. You can insert auth
|
||||
parameters.
|
||||
|
||||
- `auth_settings`
|
||||
|
||||
TODO.
|
||||
|
||||
- `api_client`
|
||||
|
||||
A reference to the `WWW::{{moduleName}}::ApiClient` object that is responsible
|
||||
for communicating with the server.
|
||||
|
||||
For example:
|
||||
|
||||
sub auth_setup_handler {
|
||||
my ($self, %p) = @_;
|
||||
$p{header_params}->{'X-TargetApp-apiKey'} = $api_key;
|
||||
$p{header_params}->{'X-TargetApp-secretKey'} = $secret_key;
|
||||
}
|
||||
|
||||
## base\_url
|
||||
|
||||
The generated code has the `base_url` already set as a default value. This method
|
||||
returns (and optionally sets) the current value of `base_url`.
|
||||
|
||||
## api\_factory
|
||||
|
||||
Returns an API factory object. You probably won't need to call this directly.
|
||||
|
||||
$self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
|
||||
|
||||
$self->pet_api; # the same
|
||||
|
||||
# MISSING METHODS
|
||||
|
||||
Most of the methods on the API are delegated to individual sub-API objects (e.g.
|
||||
Pet API, Store API, User API etc). Where different sub-APIs use the same method
|
||||
name (e.g. `new()`), these methods can't be delegated. So you need to call
|
||||
`$api->pet_api->new()`.
|
||||
|
||||
In principle, every API is susceptible to the presence of a few, random, undelegatable
|
||||
method names. In practice, because of the way method names are constructed, it's
|
||||
unlikely in general that any methods will be undelegatable, except for:
|
||||
|
||||
new()
|
||||
class_documentation()
|
||||
method_documentation()
|
||||
|
||||
To call these methods, you need to get a handle on the relevant object, either
|
||||
by calling `$api->foo_api` or by retrieving an object, e.g.
|
||||
`$api->get_pet_by_id(pet_id => $pet_id)`.
|
||||
|
||||
# BUILDING YOUR LIBRARY
|
||||
|
||||
See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
|
||||
But briefly, clone the git repository, build the codegen codebase, set up your build
|
||||
config file, then run the API build script. You will need git, Java 7 and Apache
|
||||
maven 3.0.3 or better already installed.
|
||||
|
||||
The config file should specify the project name for the generated library:
|
||||
|
||||
{"moduleName":"MyProjectName"}
|
||||
|
||||
Your library files will be built under `WWW::MyProjectName`.
|
||||
|
||||
$ git clone https://github.com/swagger-api/swagger-codegen.git
|
||||
$ cd swagger-codegen
|
||||
$ mvn package
|
||||
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
-i [URL or file path to JSON swagger API spec] \
|
||||
-l perl \
|
||||
-c /path/to/config/file.json \
|
||||
-o /path/to/output/folder
|
||||
|
||||
Bang, all done. Run the `autodoc` script in the `bin` directory to see the API
|
||||
you just built.
|
||||
|
||||
# AUTOMATIC DOCUMENTATION
|
||||
|
||||
You can print out a summary of the generated API by running the included
|
||||
`autodoc` script in the `bin` directory of your generated library.
|
||||
|
||||
# DOCUMENTATION FROM THE SWAGGER SPEC
|
||||
|
||||
Additional documentation for each class and method may be provided by the Swagger
|
||||
spec. If so, this is available via the `class_documentation()` and
|
||||
`method_documentation()` methods on each generated API and class:
|
||||
|
||||
my $cdoc = $api->pet_api->class_documentation;
|
||||
my $cmdoc = $api->pet_api->method_documentation->{$method_name};
|
||||
|
||||
my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
|
||||
my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
|
||||
|
||||
|
||||
Each of these calls returns a hashref with various useful pieces of information.
|
@ -69,6 +69,173 @@ sub _build_af {
|
||||
return WWW::{{moduleName}}::ApiFactory->new(%args);
|
||||
}
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WWW::{{moduleName}}::Role - a Moose role for the Perl Swagger Codegen project
|
||||
|
||||
=head2 A note on Moose
|
||||
|
||||
This role is the only component of the library that uses Moose. See
|
||||
WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
The Perl Swagger Codegen project builds a library of Perl modules to interact with
|
||||
a web service defined by a Swagger specification. See below for how to build the
|
||||
library.
|
||||
|
||||
This module provides an interface to the generated library. All the classes,
|
||||
objects, and methods (well, not quite *all*, see below) are flattened into this
|
||||
role.
|
||||
|
||||
package MyApp;
|
||||
use Moose;
|
||||
has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' );
|
||||
with 'WWW::{{moduleName}}::Role';
|
||||
sub auth_setup_handler {...}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyApp->new({username => $username, password => $password});
|
||||
|
||||
my $pet = $api->get_pet_by_id(pet_id => $pet_id);
|
||||
|
||||
Notice that you need to provide the code to accept the parameters passed in to C<new()>
|
||||
(by setting up attributes via the C<has> keyword). They should be used by
|
||||
C<auth_setup_handler()> to configure authentication (see below).
|
||||
|
||||
=head2 Structure of the library
|
||||
|
||||
The library consists of a set of API classes, one for each endpoint. These APIs
|
||||
implement the method calls available on each endpoint.
|
||||
|
||||
Additionally, there is a set of "object" classes, which represent the objects
|
||||
returned by and sent to the methods on the endpoints.
|
||||
|
||||
An API factory class is provided, which builds instances of each endpoint API.
|
||||
|
||||
This Moose role flattens all the methods from the endpoint APIs onto the consuming
|
||||
class. It also provides methods to retrieve the endpoint API objects, and the API
|
||||
factory object, should you need it.
|
||||
|
||||
For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 C<auth_setup_handler()>
|
||||
|
||||
This method is NOT provided - you must write it yourself. Its task is to configure
|
||||
authentication for each request.
|
||||
|
||||
The method is called on your C<$api> object and passed the following parameters:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<header_params>
|
||||
|
||||
A hashref that will become the request headers. You can insert auth
|
||||
parameters.
|
||||
|
||||
=item C<query_params>
|
||||
|
||||
A hashref that will be encoded into the request URL. You can insert auth
|
||||
parameters.
|
||||
|
||||
=item C<auth_settings>
|
||||
|
||||
TODO.
|
||||
|
||||
=item C<api_client>
|
||||
|
||||
A reference to the C<WWW::{{moduleName}}::ApiClient> object that is responsible
|
||||
for communicating with the server.
|
||||
|
||||
=back
|
||||
|
||||
For example:
|
||||
|
||||
sub auth_setup_handler {
|
||||
my ($self, %p) = @_;
|
||||
$p{header_params}->{'X-TargetApp-apiKey'} = $api_key;
|
||||
$p{header_params}->{'X-TargetApp-secretKey'} = $secret_key;
|
||||
}
|
||||
|
||||
=head2 base_url
|
||||
|
||||
The generated code has the C<base_url> already set as a default value. This method
|
||||
returns (and optionally sets) the current value of C<base_url>.
|
||||
|
||||
=head2 api_factory
|
||||
|
||||
Returns an API factory object. You probably won't need to call this directly.
|
||||
|
||||
$self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
|
||||
|
||||
$self->pet_api; # the same
|
||||
|
||||
=head1 MISSING METHODS
|
||||
|
||||
Most of the methods on the API are delegated to individual sub-API objects (e.g.
|
||||
Pet API, Store API, User API etc). Where different sub-APIs use the same method
|
||||
name (e.g. C<new()>), these methods can't be delegated. So you need to call
|
||||
C<$api-E<gt>pet_api-E<gt>new()>.
|
||||
|
||||
In principle, every API is susceptible to the presence of a few, random, undelegatable
|
||||
method names. In practice, because of the way method names are constructed, it's
|
||||
unlikely in general that any methods will be undelegatable, except for:
|
||||
|
||||
new()
|
||||
class_documentation()
|
||||
method_documentation()
|
||||
|
||||
To call these methods, you need to get a handle on the relevant object, either
|
||||
by calling C<$api-E<gt>foo_api> or by retrieving an object, e.g.
|
||||
C<$api-E<gt>get_pet_by_id(pet_id =E<gt> $pet_id)>.
|
||||
|
||||
=head1 BUILDING YOUR LIBRARY
|
||||
|
||||
See the homepage C<https://github.com/swagger-api/swagger-codegen> for full details.
|
||||
But briefly, clone the git repository, build the codegen codebase, set up your build
|
||||
config file, then run the API build script. You will need git, Java 7 and Apache
|
||||
maven 3.0.3 or better already installed.
|
||||
|
||||
The config file should specify the project name for the generated library:
|
||||
|
||||
{"moduleName":"MyProjectName"}
|
||||
|
||||
Your library files will be built under C<WWW::MyProjectName>.
|
||||
|
||||
$ git clone https://github.com/swagger-api/swagger-codegen.git
|
||||
$ cd swagger-codegen
|
||||
$ mvn package
|
||||
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
-i [URL or file path to JSON swagger API spec] \
|
||||
-l perl \
|
||||
-c /path/to/config/file.json \
|
||||
-o /path/to/output/folder
|
||||
|
||||
Bang, all done. Run the C<autodoc> script in the C<bin> directory to see the API
|
||||
you just built.
|
||||
|
||||
=head1 AUTOMATIC DOCUMENTATION
|
||||
|
||||
You can print out a summary of the generated API by running the included
|
||||
C<autodoc> script in the C<bin> directory of your generated library.
|
||||
|
||||
=head1 DOCUMENTATION FROM THE SWAGGER SPEC
|
||||
|
||||
Additional documentation for each class and method may be provided by the Swagger
|
||||
spec. If so, this is available via the C<class_documentation()> and
|
||||
C<method_documentation()> methods on each generated API and class:
|
||||
|
||||
my $cdoc = $api->pet_api->class_documentation;
|
||||
my $cmdoc = $api->pet_api->method_documentation->{$method_name};
|
||||
|
||||
my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
|
||||
my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
|
||||
|
||||
Each of these calls returns a hashref with various useful pieces of information.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
@ -73,7 +73,7 @@ sub new {
|
||||
},
|
||||
{{/allParams}}
|
||||
};
|
||||
__PACKAGE__->method_documentation->{ {{{nickname}}} } = { summary => '{{{summary}}}',
|
||||
__PACKAGE__->method_documentation->{ {{nickname}} } = { summary => '{{summary}}',
|
||||
params => $params,
|
||||
returns => {{#returnType}}'{{{returnType}}}'{{/returnType}}{{^returnType}}undef{{/returnType}},
|
||||
};
|
||||
|
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
package MyAutodoc;
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
|
||||
|
||||
use Moose;
|
||||
|
||||
with ('WWW::{{moduleName}}::Role', 'WWW::{{moduleName}}::Role::AutoDoc');
|
||||
|
||||
sub auth_setup_handler {}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyAutodoc->new;
|
||||
|
||||
print $api->autodoc;
|
||||
|
||||
exit(0);
|
164
samples/client/petstore/perl/README.md
Normal file
164
samples/client/petstore/perl/README.md
Normal file
@ -0,0 +1,164 @@
|
||||
# NAME
|
||||
|
||||
WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project
|
||||
|
||||
## A note on Moose
|
||||
|
||||
This role is the only component of the library that uses Moose. See
|
||||
WWW::SwaggerClient::ApiFactory for non-Moosey usage.
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
The Perl Swagger Codegen project builds a library of Perl modules to interact with
|
||||
a web service defined by a Swagger specification. See below for how to built the
|
||||
library.
|
||||
|
||||
This module provides an interface to the generated library. All the classes,
|
||||
objects, and methods (well, not quite \*all\*, see below) are flattened into this
|
||||
role.
|
||||
|
||||
package MyApp;
|
||||
use Moose;
|
||||
has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' );
|
||||
with 'WWW::SwaggerClient::Role';
|
||||
sub auth_setup_handler {...}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyApp->new({username => $username, password => $password});
|
||||
|
||||
my $pet = $api->get_pet_by_id(pet_id => $pet_id);
|
||||
|
||||
|
||||
Notice that you need to provide the code to accept the parameters passed in to `new()`
|
||||
(by setting up attributes via the `has` keyword). They should be used by
|
||||
`auth_setup_handler()` to configure authentication (see below).
|
||||
|
||||
## Structure of the library
|
||||
|
||||
The library consists of a set of API classes, one for each endpoint. These APIs
|
||||
implement the method calls available on each endpoint.
|
||||
|
||||
Additionally, there is a set of "object" classes, which represent the objects
|
||||
returned by and sent to the methods on the endpoints.
|
||||
|
||||
An API factory class is provided, which builds instances of each endpoint API.
|
||||
|
||||
This Moose role flattens all the methods from the endpoint APIs onto the consuming
|
||||
class. It also provides methods to retrieve the endpoint API objects, and the API
|
||||
factory object, should you need it.
|
||||
|
||||
For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
|
||||
|
||||
# METHODS
|
||||
|
||||
## `auth_setup_handler()`
|
||||
|
||||
This method is NOT provided - you must write it yourself. Its task is to configure
|
||||
authentication for each request.
|
||||
|
||||
The method is called on your `$api` object and passed the following parameters:
|
||||
|
||||
- `header_params`
|
||||
|
||||
A hashref that will become the request headers. You can insert auth
|
||||
parameters.
|
||||
|
||||
- `query_params`
|
||||
|
||||
A hashref that will be encoded into the request URL. You can insert auth
|
||||
parameters.
|
||||
|
||||
- `auth_settings`
|
||||
|
||||
TODO.
|
||||
|
||||
- `api_client`
|
||||
|
||||
A reference to the `WWW::SwaggerClient::ApiClient` object that is responsible
|
||||
for communicating with the server.
|
||||
|
||||
For example:
|
||||
|
||||
sub auth_setup_handler {
|
||||
my ($self, %p) = @_;
|
||||
$p{header_params}->{'X-TargetApp-apiKey'} = $api_key;
|
||||
$p{header_params}->{'X-TargetApp-secretKey'} = $secret_key;
|
||||
}
|
||||
|
||||
## base\_url
|
||||
|
||||
The generated code has the `base_url` already set as a default value. This method
|
||||
returns (and optionally sets) the current value of `base_url`.
|
||||
|
||||
## api\_factory
|
||||
|
||||
Returns an API factory object. You probably won't need to call this directly.
|
||||
|
||||
$self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance
|
||||
|
||||
$self->pet_api; # the same
|
||||
|
||||
# MISSING METHODS
|
||||
|
||||
Most of the methods on the API are delegated to individual sub-API objects (e.g.
|
||||
Pet API, Store API, User API etc). Where different sub-APIs use the same method
|
||||
name (e.g. `new()`), these methods can't be delegated. So you need to call
|
||||
`$api->pet_api->new()`.
|
||||
|
||||
In principle, every API is susceptible to the presence of a few, random, undelegatable
|
||||
method names. In practice, because of the way method names are constructed, it's
|
||||
unlikely in general that any methods will be undelegatable, except for:
|
||||
|
||||
new()
|
||||
class_documentation()
|
||||
method_documentation()
|
||||
|
||||
To call these methods, you need to get a handle on the relevant object, either
|
||||
by calling `$api->foo_api` or by retrieving an object, e.g.
|
||||
`$api->get_pet_by_id(pet_id => $pet_id)`.
|
||||
|
||||
# BUILDING YOUR LIBRARY
|
||||
|
||||
See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
|
||||
But briefly, clone the git repository, build the codegen codebase, set up your build
|
||||
config file, then run the API build script. You will need git, Java 7 and Apache
|
||||
maven 3.0.3 or better already installed.
|
||||
|
||||
The config file should specify the project name for the generated library:
|
||||
|
||||
{"moduleName":"MyProjectName"}
|
||||
|
||||
Your library files will be built under `WWW::MyProjectName`.
|
||||
|
||||
$ git clone https://github.com/swagger-api/swagger-codegen.git
|
||||
$ cd swagger-codegen
|
||||
$ mvn package
|
||||
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
-i [URL or file path to JSON swagger API spec] \
|
||||
-l perl \
|
||||
-c /path/to/config/file.json \
|
||||
-o /path/to/output/folder
|
||||
|
||||
Bang, all done. Run the `autodoc` script in the `bin` directory to see the API
|
||||
you just built.
|
||||
|
||||
# AUTOMATIC DOCUMENTATION
|
||||
|
||||
You can print out a summary of the generated API by running the included
|
||||
`autodoc` script in the `bin` directory of your generated library.
|
||||
|
||||
# DOCUMENTATION FROM THE SWAGGER SPEC
|
||||
|
||||
Additional documentation for each class and method may be provided by the Swagger
|
||||
spec. If so, this is available via the `class_documentation()` and
|
||||
`method_documentation()` methods on each generated API and class:
|
||||
|
||||
my $cdoc = $api->pet_api->class_documentation;
|
||||
my $cmdoc = $api->pet_api->method_documentation->{$method_name};
|
||||
|
||||
my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
|
||||
my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
|
||||
|
||||
|
||||
Each of these calls returns a hashref with various useful pieces of information.
|
19
samples/client/petstore/perl/bin/autodoc
Normal file
19
samples/client/petstore/perl/bin/autodoc
Normal file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
package MyAutodoc;
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
|
||||
|
||||
use Moose;
|
||||
|
||||
with ('WWW::SwaggerClient::Role', 'WWW::SwaggerClient::Role::AutoDoc');
|
||||
|
||||
sub auth_setup_handler {}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyAutodoc->new;
|
||||
|
||||
print $api->autodoc;
|
||||
|
||||
exit(0);
|
@ -69,6 +69,173 @@ sub _build_af {
|
||||
return WWW::SwaggerClient::ApiFactory->new(%args);
|
||||
}
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WWW::SwaggerClient::Role - a Moose role for the Perl Swagger Codegen project
|
||||
|
||||
=head2 A note on Moose
|
||||
|
||||
This role is the only component of the library that uses Moose. See
|
||||
WWW::SwaggerClient::ApiFactory for non-Moosey usage.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
The Perl Swagger Codegen project builds a library of Perl modules to interact with
|
||||
a web service defined by a Swagger specification. See below for how to build the
|
||||
library.
|
||||
|
||||
This module provides an interface to the generated library. All the classes,
|
||||
objects, and methods (well, not quite *all*, see below) are flattened into this
|
||||
role.
|
||||
|
||||
package MyApp;
|
||||
use Moose;
|
||||
has [qw(username password)] => ( is => 'ro', required => 1, isa => 'Str' );
|
||||
with 'WWW::SwaggerClient::Role';
|
||||
sub auth_setup_handler {...}
|
||||
|
||||
package main;
|
||||
|
||||
my $api = MyApp->new({username => $username, password => $password});
|
||||
|
||||
my $pet = $api->get_pet_by_id(pet_id => $pet_id);
|
||||
|
||||
Notice that you need to provide the code to accept the parameters passed in to C<new()>
|
||||
(by setting up attributes via the C<has> keyword). They should be used by
|
||||
C<auth_setup_handler()> to configure authentication (see below).
|
||||
|
||||
=head2 Structure of the library
|
||||
|
||||
The library consists of a set of API classes, one for each endpoint. These APIs
|
||||
implement the method calls available on each endpoint.
|
||||
|
||||
Additionally, there is a set of "object" classes, which represent the objects
|
||||
returned by and sent to the methods on the endpoints.
|
||||
|
||||
An API factory class is provided, which builds instances of each endpoint API.
|
||||
|
||||
This Moose role flattens all the methods from the endpoint APIs onto the consuming
|
||||
class. It also provides methods to retrieve the endpoint API objects, and the API
|
||||
factory object, should you need it.
|
||||
|
||||
For documentation of all these methods, see AUTOMATIC DOCUMENTATION below.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 C<auth_setup_handler()>
|
||||
|
||||
This method is NOT provided - you must write it yourself. Its task is to configure
|
||||
authentication for each request.
|
||||
|
||||
The method is called on your C<$api> object and passed the following parameters:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<header_params>
|
||||
|
||||
A hashref that will become the request headers. You can insert auth
|
||||
parameters.
|
||||
|
||||
=item C<query_params>
|
||||
|
||||
A hashref that will be encoded into the request URL. You can insert auth
|
||||
parameters.
|
||||
|
||||
=item C<auth_settings>
|
||||
|
||||
TODO.
|
||||
|
||||
=item C<api_client>
|
||||
|
||||
A reference to the C<WWW::SwaggerClient::ApiClient> object that is responsible
|
||||
for communicating with the server.
|
||||
|
||||
=back
|
||||
|
||||
For example:
|
||||
|
||||
sub auth_setup_handler {
|
||||
my ($self, %p) = @_;
|
||||
$p{header_params}->{'X-TargetApp-apiKey'} = $api_key;
|
||||
$p{header_params}->{'X-TargetApp-secretKey'} = $secret_key;
|
||||
}
|
||||
|
||||
=head2 base_url
|
||||
|
||||
The generated code has the C<base_url> already set as a default value. This method
|
||||
returns (and optionally sets) the current value of C<base_url>.
|
||||
|
||||
=head2 api_factory
|
||||
|
||||
Returns an API factory object. You probably won't need to call this directly.
|
||||
|
||||
$self->api_factory('Pet'); # returns a WWW::SwaggerClient::PetApi instance
|
||||
|
||||
$self->pet_api; # the same
|
||||
|
||||
=head1 MISSING METHODS
|
||||
|
||||
Most of the methods on the API are delegated to individual sub-API objects (e.g.
|
||||
Pet API, Store API, User API etc). Where different sub-APIs use the same method
|
||||
name (e.g. C<new()>), these methods can't be delegated. So you need to call
|
||||
C<$api-E<gt>pet_api-E<gt>new()>.
|
||||
|
||||
In principle, every API is susceptible to the presence of a few, random, undelegatable
|
||||
method names. In practice, because of the way method names are constructed, it's
|
||||
unlikely in general that any methods will be undelegatable, except for:
|
||||
|
||||
new()
|
||||
class_documentation()
|
||||
method_documentation()
|
||||
|
||||
To call these methods, you need to get a handle on the relevant object, either
|
||||
by calling C<$api-E<gt>foo_api> or by retrieving an object, e.g.
|
||||
C<$api-E<gt>get_pet_by_id(pet_id =E<gt> $pet_id)>.
|
||||
|
||||
=head1 BUILDING YOUR LIBRARY
|
||||
|
||||
See the homepage C<https://github.com/swagger-api/swagger-codegen> for full details.
|
||||
But briefly, clone the git repository, build the codegen codebase, set up your build
|
||||
config file, then run the API build script. You will need git, Java 7 and Apache
|
||||
maven 3.0.3 or better already installed.
|
||||
|
||||
The config file should specify the project name for the generated library:
|
||||
|
||||
{"moduleName":"MyProjectName"}
|
||||
|
||||
Your library files will be built under C<WWW::MyProjectName>.
|
||||
|
||||
$ git clone https://github.com/swagger-api/swagger-codegen.git
|
||||
$ cd swagger-codegen
|
||||
$ mvn package
|
||||
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
|
||||
-i [URL or file path to JSON swagger API spec] \
|
||||
-l perl \
|
||||
-c /path/to/config/file.json \
|
||||
-o /path/to/output/folder
|
||||
|
||||
Bang, all done. Run the C<autodoc> script in the C<bin> directory to see the API
|
||||
you just built.
|
||||
|
||||
=head1 AUTOMATIC DOCUMENTATION
|
||||
|
||||
You can print out a summary of the generated API by running the included
|
||||
C<autodoc> script in the C<bin> directory of your generated library.
|
||||
|
||||
=head1 DOCUMENTATION FROM THE SWAGGER SPEC
|
||||
|
||||
Additional documentation for each class and method may be provided by the Swagger
|
||||
spec. If so, this is available via the C<class_documentation()> and
|
||||
C<method_documentation()> methods on each generated API and class:
|
||||
|
||||
my $cdoc = $api->pet_api->class_documentation;
|
||||
my $cmdoc = $api->pet_api->method_documentation->{$method_name};
|
||||
|
||||
my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation;
|
||||
my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name};
|
||||
|
||||
Each of these calls returns a hashref with various useful pieces of information.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
@ -0,0 +1,156 @@
|
||||
package WWW::SwaggerClient::Role::AutoDoc;
|
||||
use List::MoreUtils qw(uniq);
|
||||
|
||||
use Moose::Role;
|
||||
|
||||
sub autodoc {
|
||||
my $self = shift;
|
||||
|
||||
$self->_printisa;
|
||||
$self->_printmethods;
|
||||
$self->_printattrs;
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub _printisa {
|
||||
my $self = shift;
|
||||
my $meta = $self->meta;
|
||||
|
||||
my $myclass = ref $self;
|
||||
|
||||
my $super = join ', ', $meta->superclasses;
|
||||
my @roles = $meta->calculate_all_roles;
|
||||
shift(@roles); # the first is a composite, the rest are the roles
|
||||
|
||||
my $isa = join ', ', $meta->linearized_isa;
|
||||
my $sub = join ', ', $meta->subclasses;
|
||||
my $dsub = join ', ', $meta->direct_subclasses;
|
||||
|
||||
my ($rolepkg, $role_reqs);
|
||||
|
||||
$~ = 'INHERIT';
|
||||
write;
|
||||
|
||||
foreach my $role (@roles) {
|
||||
$rolepkg = $role->{package};
|
||||
$role_reqs = join ', ', keys %{$role->{required_methods}};
|
||||
$~ = 'ROLES';
|
||||
write;
|
||||
}
|
||||
|
||||
# ----- format specs -----
|
||||
format INHERIT =
|
||||
|
||||
@* -
|
||||
$myclass
|
||||
ISA: @*
|
||||
$isa
|
||||
Direct subclasses: @*
|
||||
$dsub
|
||||
All subclasses: @*
|
||||
$sub
|
||||
.
|
||||
format ROLES =
|
||||
Composes: @*
|
||||
$rolepkg
|
||||
requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
|
||||
$role_reqs
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
sub _printmethods {
|
||||
my $self = shift;
|
||||
$~ = 'METHODHEAD';
|
||||
write;
|
||||
$self->_printmethod($_) for uniq sort $self->meta->get_method_list, $self->meta->get_all_method_names;
|
||||
}
|
||||
|
||||
sub _printmethod {
|
||||
my ($self, $methodname) = @_;
|
||||
return if $methodname =~ /^_/;
|
||||
return if $self->meta->has_attribute($methodname);
|
||||
my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY
|
||||
DOES isa BUILDALL does VERSION dump
|
||||
);
|
||||
return if $internal{$methodname};
|
||||
my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose
|
||||
|
||||
return if $method->original_package_name eq __PACKAGE__;
|
||||
|
||||
my $delegation = '';
|
||||
my $delegate_to = '';
|
||||
my $via = '';
|
||||
my $on = '';
|
||||
if ($method->can('associated_attribute')) {
|
||||
$delegate_to = $method->delegate_to_method;
|
||||
my $aa = $method->associated_attribute;
|
||||
$on = $aa->{isa};
|
||||
$via = $aa->{name};
|
||||
}
|
||||
|
||||
$~ = 'METHOD';
|
||||
write;
|
||||
|
||||
# ----- format specs -----
|
||||
format METHODHEAD =
|
||||
|
||||
METHODS
|
||||
-------
|
||||
Name delegate to on via
|
||||
===================================================================================================================================
|
||||
.
|
||||
format METHOD =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<...
|
||||
$methodname, $delegate_to, $on, $via
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
sub _printattrs {
|
||||
my $self = shift;
|
||||
$~ = 'ATTRHEAD';
|
||||
write;
|
||||
$self->_printattr($_) for sort $self->meta->get_attribute_list;
|
||||
}
|
||||
|
||||
sub _printattr {
|
||||
my ($self, $attrname) = @_;
|
||||
return if $attrname =~ /^_/;
|
||||
my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname";
|
||||
|
||||
my $is;
|
||||
$is = 'rw' if $attr->get_read_method && $attr->get_write_method;
|
||||
$is = 'ro' if $attr->get_read_method && ! $attr->get_write_method;
|
||||
$is = 'wo' if $attr->get_write_method && ! $attr->get_read_method;
|
||||
$is = '--' if ! $attr->get_write_method && ! $attr->get_read_method;
|
||||
$is or die "No \$is for $attrname";
|
||||
|
||||
my $tc = $attr->type_constraint || '';
|
||||
my $from = $attr->associated_class->name || '';
|
||||
my $reqd = $attr->is_required ? 'reqd' : 'opt';
|
||||
my $lazy = $attr->is_lazy ? 'lazy' : '';
|
||||
my $doc = $attr->has_documentation ? 'yes' : '';
|
||||
my $handles = join ', ', sort @{$attr->handles || []};
|
||||
|
||||
$~ = 'ATTR';
|
||||
write;
|
||||
|
||||
# ----- format specs -----
|
||||
format ATTRHEAD =
|
||||
|
||||
ATTRIBUTES
|
||||
----------
|
||||
Name is isa reqd lazy doc handles
|
||||
==============================================================================================================
|
||||
.
|
||||
format ATTR =
|
||||
@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$attrname, $is, $tc, $reqd, $lazy, $doc, $handles
|
||||
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
|
||||
$handles
|
||||
.
|
||||
# ----- / format specs -----
|
||||
}
|
||||
|
||||
1;
|
@ -7,10 +7,6 @@ use lib 'lib';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use MooseX::amine;
|
||||
use Class::Inspector;
|
||||
use Data::Dumper;
|
||||
|
||||
SKIP: {
|
||||
eval "
|
||||
package MyApp;
|
||||
|
Loading…
Reference in New Issue
Block a user