.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "OpenAPI::Client 3pm" .TH OpenAPI::Client 3pm "2022-10-30" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" OpenAPI::Client \- A client for talking to an Open API powered server .SH "DESCRIPTION" .IX Header "DESCRIPTION" OpenAPI::Client can generating classes that can talk to an Open \s-1API\s0 server. This is done by generating a custom class, based on a Open \s-1API\s0 specification, with methods that transform parameters into a \s-1HTTP\s0 request. .PP The generated class will perform input validation, so invalid data won't be sent to the server. .PP Note that this implementation is currently \s-1EXPERIMENTAL,\s0 but unlikely to change! Feedback is appreciated. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .SS "Open \s-1API\s0 specification" .IX Subsection "Open API specification" The specification given to \*(L"new\*(R" need to point to a valid OpenAPI document. This document can be OpenAPI v2.x or v3.x, and it can be in either \s-1JSON\s0 or \s-1YAML\s0 format. Example: .PP .Vb 11 \& openapi: 3.0.1 \& info: \& title: Swagger Petstore \& version: 1.0.0 \& servers: \& \- url: http://petstore.swagger.io/v1 \& paths: \& /pets: \& get: \& operationId: listPets \& ... .Ve .PP \&\f(CW\*(C`host\*(C'\fR, \f(CW\*(C`basePath\*(C'\fR and the first item in \f(CW\*(C`schemes\*(C'\fR will be used to construct \&\*(L"base_url\*(R". This can be altered at any time, if you need to send data to a custom endpoint. .SS "Client" .IX Subsection "Client" The OpenAPI \s-1API\s0 specification will be used to generate a sub-class of OpenAPI::Client where the \*(L"operationId\*(R", inside of each path definition, is used to generate methods: .PP .Vb 2 \& use OpenAPI::Client; \& $client = OpenAPI::Client\->new("file:///path/to/api.json"); \& \& # Blocking \& $tx = $client\->listPets; \& \& # Non\-blocking \& $client = $client\->listPets(sub { my ($client, $tx) = @_; }); \& \& # Promises \& $promise = $client\->listPets_p\->then(sub { my $tx = shift }); \& \& # With parameters \& $tx = $client\->listPets({limit => 10}); .Ve .PP See Mojo::Transaction for more information about what you can do with the \&\f(CW$tx\fR object, but you often just want something like this: .PP .Vb 2 \& # Check for errors \& die $tx\->error\->{message} if $tx\->error; \& \& # Extract data from the JSON responses \& say $tx\->res\->json\->{pets}[0]{name}; .Ve .PP Check out \*(L"error\*(R" in Mojo::Transaction, \*(L"req\*(R" in Mojo::Transaction and \&\*(L"res\*(R" in Mojo::Transaction for some of the most used methods in that class. .SH "CUSTOMIZATION" .IX Header "CUSTOMIZATION" .SS "Custom server \s-1URL\s0" .IX Subsection "Custom server URL" If you want to request a different server than what is specified in the Open \&\s-1API\s0 document, you can change the \*(L"base_url\*(R": .PP .Vb 3 \& # Pass on a Mojo::URL object to the constructor \& $base_url = Mojo::URL\->new("http://example.com"); \& $client1 = OpenAPI::Client\->new("file:///path/to/api.json", base_url => $base_url); \& \& # A plain string will be converted to a Mojo::URL object \& $client2 = OpenAPI::Client\->new("file:///path/to/api.json", base_url => "http://example.com"); \& \& # Change the base_url after the client has been created \& $client3 = OpenAPI::Client\->new("file:///path/to/api.json"); \& $client3\->base_url\->host("other.example.com"); .Ve .SS "Custom content" .IX Subsection "Custom content" You can send \s-1XML\s0 or any format you like, but this require you to add a new \&\*(L"generator\*(R": .PP .Vb 6 \& use Your::XML::Library "to_xml"; \& $client\->ua\->transactor\->add_generator(xml => sub { \& my ($t, $tx, $data) = @_; \& $tx\->req\->body(to_xml $data); \& return $tx; \& }); \& \& $client\->addHero({}, xml => {name => "Supergirl"}); .Ve .PP See Mojo::UserAgent::Transactor for more details. .SH "EVENTS" .IX Header "EVENTS" .SS "after_build_tx" .IX Subsection "after_build_tx" .Vb 1 \& $client\->on(after_build_tx => sub { my ($client, $tx) = @_ }) .Ve .PP This event is emitted after a Mojo::UserAgent::Transactor object has been built, just before it is passed on to the \*(L"ua\*(R". Note that all validation has already been run, so alternating the \f(CW$tx\fR too much, might cause an invalid request on the server side. .PP A special \*(L"env\*(R" in Mojo::Message::Request variable will be set, to reference the operationId: .PP .Vb 1 \& $tx\->req\->env\->{operationId}; .Ve .PP Note that this usage of \f(CW\*(C`env()\*(C'\fR is currently \s-1EXPERIMENTAL:\s0 .SH "ATTRIBUTES" .IX Header "ATTRIBUTES" .SS "base_url" .IX Subsection "base_url" .Vb 1 \& $base_url = $client\->base_url; .Ve .PP Returns a Mojo::URL object with the base \s-1URL\s0 to the \s-1API.\s0 The default value comes from \f(CW\*(C`schemes\*(C'\fR, \f(CW\*(C`basePath\*(C'\fR and \f(CW\*(C`host\*(C'\fR in the OpenAPI v2 specification or from \f(CW\*(C`servers\*(C'\fR in the OpenAPI v3 specification. .SS "ua" .IX Subsection "ua" .Vb 1 \& $ua = $client\->ua; .Ve .PP Returns a Mojo::UserAgent object which is used to execute requests. .SH "METHODS" .IX Header "METHODS" .SS "call" .IX Subsection "call" .Vb 2 \& $tx = $client\->call($operationId => \e%params, %content); \& $client = $client\->call($operationId => \e%params, %content, sub { my ($client, $tx) = @_; }); .Ve .PP Used to either call an \f(CW$operationId\fR that has an \*(L"invalid name\*(R", such as \&\*(L"list pets\*(R" instead of \*(L"listPets\*(R" or to call an \f(CW$operationId\fR that you are unsure is supported yet. If it is not, an exception will be thrown, matching text \*(L"No such operationId\*(R". .PP \&\f(CW$operationId\fR is the name of the resource defined in the OpenAPI specification . .PP \&\f(CW$params\fR is optional, but must be a hash ref, where the keys should match a named parameter in the OpenAPI specification . .PP \&\f(CW%content\fR is used for the body of the request, where the key need to be either \*(L"body\*(R" or a matching \*(L"generators\*(R" in Mojo::UserAgent::Transactor. Example: .PP .Vb 2 \& $client\->addHero({}, body => "Some data"); \& $client\->addHero({}, json => {name => "Supergirl"}); .Ve .PP \&\f(CW$tx\fR is a Mojo::Transaction object. .SS "call_p" .IX Subsection "call_p" .Vb 2 \& $promise = $client\->call_p($operationId => $params, %content); \& $promise\->then(sub { my $tx = shift }); .Ve .PP As \*(L"call\*(R" above, but returns a Mojo::Promise object. .SS "new" .IX Subsection "new" .Vb 2 \& $client = OpenAPI::Client\->new($specification, \e%attributes); \& $client = OpenAPI::Client\->new($specification, %attributes); .Ve .PP Returns an object of a generated class, with methods generated from the Open \&\s-1API\s0 specification located at \f(CW$specification\fR. See \*(L"schema\*(R" in JSON::Validator for valid versions of \f(CW$specification\fR. .PP Note that the class is cached by perl, so loading a new specification from the same \s-1URL\s0 will not generate a new class. .PP Extra \f(CW%attributes\fR: .IP "\(bu" 2 app .Sp Specifying an \f(CW\*(C`app\*(C'\fR is useful when running against a local Mojolicious instance. .IP "\(bu" 2 coerce .Sp See \*(L"coerce\*(R" in JSON::Validator. Default to \*(L"booleans,numbers,strings\*(R". .SS "validator" .IX Subsection "validator" .Vb 2 \& $validator = $client\->validator; \& $validator = $class\->validator; .Ve .PP Returns a JSON::Validator::Schema::OpenAPIv2 object for a generated class. Note that this is a global variable, so changing the object will affect all instances returned by \*(L"new\*(R". .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2017\-2021, Jan Henning Thorsen .PP This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. .SH "AUTHORS" .IX Header "AUTHORS" .SS "Project Founder" .IX Subsection "Project Founder" Jan Henning Thorsen \- \f(CW\*(C`jhthorsen@cpan.org\*(C'\fR .SS "Contributors" .IX Subsection "Contributors" .IP "\(bu" 2 Clive Holloway .IP "\(bu" 2 Ed J .IP "\(bu" 2 Jan Henning Thorsen .IP "\(bu" 2 Jan Henning Thorsen .IP "\(bu" 2 Mohammad S Anwar .IP "\(bu" 2 Reneeb .IP "\(bu" 2 Roy Storey .IP "\(bu" 2 Veesh Goldman