Created by: richardwhiuk
This adds support for callbacks to Rust Server. This is a reasonable substantial change to the templates - mainly to prevent duplication between the server and client cases.
This work was done by myself on behalf of @Metaswitch, and has been reviewed, tested and fixed by others @Metaswitch.
Design
The key change that callbacks make is that the server now needs to act as a client (in order to send callbacks), and the client needs to act as a server (in order to receive callbacks).
As such, we modify the generator to produce a api::server::callbacks
and a api::client::callbacks
module. These are only generated if the API uses callbacks (to avoid making non callback using API code more complex).
api::server::callbacks
provides a Client which implements all of the callback APIs from a server perspective. This is largely similar in nature to api::client
.
api::client::callbacks
provides a Service which implements all of the callback APIs from a client perspective. This provides a Service which can be implemented by the client. This is largely identical to api::server.
Implementation
Low level details of what's happened:
-
Rust changes:
-
We now generate two different Path Set Maps, which contain the paths to generate - one for the callbacks, and one for the general set.
-
We recursively postProcessModelsWithOperations, so that we can add metadata to the operations in callbacks.
-
We add the callback mustache files if any of the operations have callbacks. We also annotate the API with whether it has callbacks, and include the path set map.
-
-
Mustache template composition is used extensively.
-
mimetype.rs
is now formed frommimetype.mustache
,mimetype-request.mustache
andmimetype-response.mustache
.This pulls out the logic for generating mimetypes for a request/response into individual files, which can then be included per request/response.
This is exploited to generate mimetypes for callback operations, without duplication.
-
lib.rs
is formed fromlib.mustache
, andresponse.mustache
which contains the common definition for a Response type. -
client/mod.rs
is now formed from:-
client-mod.mustache
the base, as before -
client-import.mustache
which contains imports common to the clients. -
client-api.mustache
which defines how a Client implements an OpenAPI operation
-
-
server/mod.rs
is now formed from:-
server-mod.mustache
the base, as before -
server-imports.mustache
which contains imports common to the servers. -
server-paths.mustache
which determines the regular expressions used to match the operations -
server-make-service.mustache
which the MakeService definition -
server-service-header.mustache
which contains the Service definition, and implementation prelude -
server-service-footer.mustache
which contains the Service implementation ending -
server-operation.mustache
which provides the implementation of an OpenAPI operation
-
-
client/callbacks.rs
is new, and uses the same skeleton asserver/mod.rs
, with most of the same includes (as this contains the client's server). -
server/callbacks.rs
is new, and uses the same skeleton asclient/mod.rs
. -
A similar task is solved in the examples as well:
-
examples/server/server.rs
consists of:-
examples-server-server.mustache
- the base structure -
examples-server-common.mustache
- the common definition and creation code -
examples-server-api.mustache
- which provides the dummy implementation of an OpenAPI operation
-
-
example/client/server.rs
is the client's callback server, and uses the same core set of templates asexamples/server/server.rs
.
-
-
-
We restructure the examples to use Rust's recommend model for multi-file examples:
- examples/
- server/
- main.rs
- server.rs
- server/
- examples/
-
We move the examples to use
log
andenv_logger
instead of justprintln!
-
We fix a bug where the examples README suggests examples exist, even if we failed to generate code for them.
Limitations
-
We make no attempt to support nested callbacks (i.e. callbacks of callbacks). This would be a further enhancement if there's desire to support this.
-
Currently we provide a single callback API, and require the implementor to implement all the functions.
Rust Server Technical Committee
- @frol
- @farcaller
- @bjgill
PR checklist
-
Read the contribution guidelines. -
If contributing template-only or documentation-only changes which will change sample output, build the project before. -
Run the shell script(s) under ./bin/
(or Windows batch scripts under.\bin\windows
) to update Petstore samples related to your fix. This is important, as CI jobs will verify all generator outputs of your HEAD commit, and these must match the expectations made by your contribution. You only need to run./bin/{LANG}-petstore.sh
,./bin/openapi3/{LANG}-petstore.sh
if updating the code or mustache templates for a language ({LANG}
) (e.g. php, ruby, python, etc). -
File the PR against the correct branch: master
,4.3.x
,5.0.x
. Default:master
. -
Copy the technical committee to review the pull request if your PR is targeting a particular programming language.