mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-05-18 15:40:53 +00:00
400 lines
59 KiB
HTML
400 lines
59 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Create a New Generator · OpenAPI Generator</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="Creating a new generator which will become a part of the officially supported generators in OpenAPI Generator is pretty simple. We've created a helper script to bootstrap the operation. Let's look at the files necessary to create a new generator, then an example of bootstrapping a generator using the `new.sh` script in the root of the repository."/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Create a New Generator · OpenAPI Generator"/><meta property="og:type" content="website"/><meta property="og:url" content="https://openapi-generator.tech/"/><meta property="og:description" content="Creating a new generator which will become a part of the officially supported generators in OpenAPI Generator is pretty simple. We've created a helper script to bootstrap the operation. Let's look at the files necessary to create a new generator, then an example of bootstrapping a generator using the `new.sh` script in the root of the repository."/><meta property="og:image" content="https://openapi-generator.tech/img/docusaurus.png"/><meta name="twitter:card" content="summary"/><meta name="twitter:image" content="https://openapi-generator.tech/img/icons/twitter.svg"/><link rel="shortcut icon" href="/img/favicon.png"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"/><link rel="alternate" type="application/atom+xml" href="https://openapi-generator.tech/blog/atom.xml" title="OpenAPI Generator Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://openapi-generator.tech/blog/feed.xml" title="OpenAPI Generator Blog RSS Feed"/><script>
|
||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||
|
||
ga('create', 'UA-132927057-1', 'auto');
|
||
ga('send', 'pageview');
|
||
</script><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script><script type="text/javascript" src="/js/code-block-buttons.js"></script><script src="https://unpkg.com/vanilla-back-to-top@7.1.14/dist/vanilla-back-to-top.min.js"></script><script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
addBackToTop(
|
||
{"zIndex":100}
|
||
)
|
||
});
|
||
</script><script src="/js/scrollSpy.js"></script><link rel="stylesheet" href="/css/main.css"/><script src="/js/codetabs.js"></script></head><body class="sideNavVisible separateOnPageNav"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/"><img class="logo" src="/img/mono-logo.svg" alt="OpenAPI Generator"/><h2 class="headerTitleWithLogo">OpenAPI Generator</h2></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavGroupActive"><a href="/docs/installation" target="_self">Get Started</a></li><li class="siteNavGroupActive"><a href="/docs/generators" target="_self">Generators</a></li><li class="siteNavGroupActive"><a href="/docs/roadmap" target="_self">Roadmap</a></li><li class=""><a href="/team" target="_self">Team</a></li><li class=""><a href="/docs/faq" target="_self">FAQ</a></li><li class=""><a href="/blog/" target="_self">Blog</a></li></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><div class="hamburger-menu"><div class="line1"></div><div class="line2"></div><div class="line3"></div></div></div><h2><i>›</i><span>Contributing</span></h2><div class="tocToggler" id="tocToggler"><i class="icon-toc"></i></div></div><div class="navGroups"><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Getting Started<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/installation">CLI Installation</a></li><li class="navListItem"><a class="navItem" href="/docs/plugins">Plugins</a></li><li class="navListItem"><a class="navItem" href="/docs/online">Online</a></li><li class="navListItem"><a class="navItem" href="/docs/usage">Usage</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Extending<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/templating">Using Templates</a></li><li class="navListItem"><a class="navItem" href="/docs/customization">Customization</a></li><li class="navListItem"><a class="navItem" href="/docs/debugging">Debugging</a></li><li class="navListItem"><a class="navItem" href="/docs/integrations">Workflow Integrations</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Contributing<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/contributing">Guidelines</a></li><li class="navListItem"><a class="navItem" href="/docs/code-of-conduct">Code of Conduct</a></li><li class="navListItem"><a class="navItem" href="/docs/contribute-building">Building the code</a></li><li class="navListItem navListItemActive"><a class="navItem" href="/docs/new-generator">Create a New Generator</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">About<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/roadmap">Roadmap</a></li><li class="navListItem"><a class="navItem" href="/docs/swagger-codegen-migration">Migrating from Swagger Codegen</a></li><li class="navListItem"><a class="navItem" href="/docs/fork-qna">Swagger Codegen Fork: Q&A</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">Releases<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/release-summary">Release Summary</a></li><li class="navListItem"><a class="navItem" href="/docs/release-3-0-0">Release Notes: 3.0.0</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle collapsible">API<span class="arrow"><svg width="24" height="24" viewBox="0 0 24 24"><path fill="#565656" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span></h3><ul class="hide"><li class="navListItem"><a class="navItem" href="/docs/generators">Generators List</a></li></ul></div></div></section></div><script>
|
||
var coll = document.getElementsByClassName('collapsible');
|
||
var checkActiveCategory = true;
|
||
for (var i = 0; i < coll.length; i++) {
|
||
var links = coll[i].nextElementSibling.getElementsByTagName('*');
|
||
if (checkActiveCategory){
|
||
for (var j = 0; j < links.length; j++) {
|
||
if (links[j].classList.contains('navListItemActive')){
|
||
coll[i].nextElementSibling.classList.toggle('hide');
|
||
coll[i].childNodes[1].classList.toggle('rotate');
|
||
checkActiveCategory = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
coll[i].addEventListener('click', function() {
|
||
var arrow = this.childNodes[1];
|
||
arrow.classList.toggle('rotate');
|
||
var content = this.nextElementSibling;
|
||
content.classList.toggle('hide');
|
||
});
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
createToggler('#navToggler', '#docsNav', 'docsSliderActive');
|
||
createToggler('#tocToggler', 'body', 'tocActive');
|
||
|
||
var headings = document.querySelector('.toc-headings');
|
||
headings && headings.addEventListener('click', function(event) {
|
||
var el = event.target;
|
||
while(el !== headings){
|
||
if (el.tagName === 'A') {
|
||
document.body.classList.remove('tocActive');
|
||
break;
|
||
} else{
|
||
el = el.parentNode;
|
||
}
|
||
}
|
||
}, false);
|
||
|
||
function createToggler(togglerSelector, targetSelector, className) {
|
||
var toggler = document.querySelector(togglerSelector);
|
||
var target = document.querySelector(targetSelector);
|
||
|
||
if (!toggler) {
|
||
return;
|
||
}
|
||
|
||
toggler.onclick = function(event) {
|
||
event.preventDefault();
|
||
|
||
target.classList.toggle(className);
|
||
};
|
||
}
|
||
});
|
||
</script></nav></div><div class="container mainContainer docsContainer"><div class="wrapper"><div class="post"><header class="postHeader"><h1 id="__docusaurus" class="postHeaderTitle">Create a New Generator</h1></header><article><div><span><p>Creating a new generator which will become a part of the officially supported generators in OpenAPI Generator is pretty simple. We've created a helper script to bootstrap the operation. Let's look at the files necessary to create a new generator, then an example of bootstrapping a generator using the <code>new.sh</code> script in the root of the repository.</p>
|
||
<h2><a class="anchor" aria-hidden="true" id="required-files"></a><a href="#required-files" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Required Files</h2>
|
||
<p>The minimum set of files required to create a new generator are:</p>
|
||
<ul>
|
||
<li>A "Codegen" file
|
||
<ul>
|
||
<li>exists under <code>modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/</code></li>
|
||
<li>defines language options</li>
|
||
<li>defines framework options</li>
|
||
<li>determines OpenAPI feature set</li>
|
||
<li>extends the generation workflow</li>
|
||
</ul></li>
|
||
<li>SPI registration
|
||
<ul>
|
||
<li>Above class must be referenced in <code>modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig</code></li>
|
||
<li>Tells the generator that this class exists</li>
|
||
<li>Allows for classpath extension (addition) of generators</li>
|
||
</ul></li>
|
||
<li>A minimal template
|
||
<ul>
|
||
<li>Should include a README explaining usage</li>
|
||
<li>Must include an <code>api.mustache</code></li>
|
||
<li>Exists under <code>modules/openapi-generator/src/main/resources/</code> (plus <code>embeddedTemplate</code> dir value, see below)</li>
|
||
</ul></li>
|
||
<li>Sample scripts under <code>./bin</code> and <code>./bin/windows</code>
|
||
<ul>
|
||
<li>Gives users a "real life" example of generated output</li>
|
||
<li>Samples are used by CI to verify generators and test for regressions in some cases</li>
|
||
</ul></li>
|
||
</ul>
|
||
<p>Now, let's generate an example generator and then walk through the pieces. At the end, we'll touch on some known sticking points for new generator authors and provide some suggestions.</p>
|
||
<h2><a class="anchor" aria-hidden="true" id="newsh"></a><a href="#newsh" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>new.sh</h2>
|
||
<p>The <code>new.sh</code> script in the root of the project is meant to simplify this process. Run <code>./new.sh --help</code>.</p>
|
||
<pre><code class="hljs css language-text">Stubs out files for new generators
|
||
|
||
Usage:
|
||
./new.sh [options]
|
||
Options:
|
||
-n Required. Specify generator name, should be kebab-cased.
|
||
-c Create a client generator
|
||
-s Create a server generator
|
||
-d Create a documentation generator
|
||
-t When specified, creates test file(s) for the generator.
|
||
-h Display help.
|
||
|
||
Examples:
|
||
Create a server generator for ktor:
|
||
./new.sh -n kotlin -s
|
||
|
||
Creates:
|
||
modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java
|
||
modules/openapi-generator/src/main/resources/kotlin-server/README.mustache
|
||
modules/openapi-generator/src/main/resources/kotlin-server/model.mustache
|
||
modules/openapi-generator/src/main/resources/kotlin-server/api.mustache
|
||
bin/windows/kotlin-server-petstore.bat
|
||
bin/kotlin-server-petstore.sh
|
||
|
||
Create a generic C# server generator:
|
||
./new.sh -n csharp -s -t
|
||
Creates:
|
||
modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CsharpServerCodegen.java
|
||
modules/openapi-generator/src/main/resources/csharp-server/README.mustache
|
||
modules/openapi-generator/src/main/resources/csharp-server/model.mustache
|
||
modules/openapi-generator/src/main/resources/csharp-server/api.mustache
|
||
bin/windows/csharp-server-petstore.bat
|
||
bin/csharp-server-petstore.sh
|
||
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenTest.java
|
||
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenModelTest.java
|
||
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenOptionsTest.java
|
||
modules/openapi-generator/src/test/java/org/openapitools/codegen/options/CsharpServerCodegenOptionsProvider.java
|
||
</code></pre>
|
||
<p>This script allows us to define a client, server, schema, or documentation generator. We'll focus on the simplest generator (documentation). The other generator types may require heavy extension of the "Config" base class, and these docs could very quickly become outdated. When creating a new generator, please review existing generators as a guideline for implementation.</p>
|
||
<p>Create a new Markdown generator, specifying CommonMark as the name to avoid conflicting with the built-in Markdown generator.</p>
|
||
<pre><code class="hljs css language-bash">./new.sh -n common-mark -d
|
||
</code></pre>
|
||
<p>You should see output similar to the following:</p>
|
||
<pre><code class="hljs css language-bash">Creating modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CommonMarkDocumentationCodegen.java
|
||
Creating modules/openapi-generator/src/main/resources/common-mark-documentation/README.mustache
|
||
Creating modules/openapi-generator/src/main/resources/common-mark-documentation/model.mustache
|
||
Creating modules/openapi-generator/src/main/resources/common-mark-documentation/api.mustache
|
||
Creating bin/windows/common-mark-documentation-petstore.bat
|
||
Creating bin/common-mark-documentation-petstore.sh
|
||
Finished.
|
||
</code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" id="review-generated-config"></a><a href="#review-generated-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Review Generated Config</h3>
|
||
<p>Beginning with the "Codegen" file (<code>CommonMarkDocumentationCodegen.java</code>), the constructor was created:</p>
|
||
<pre><code class="hljs css language-java"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CommonMarkDocumentationCodegen</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">super</span>();
|
||
|
||
outputFolder = <span class="hljs-string">"generated-code"</span> + File.separator + <span class="hljs-string">"common-mark"</span>;
|
||
modelTemplateFiles.put(<span class="hljs-string">"model.mustache"</span>, <span class="hljs-string">".zz"</span>);
|
||
apiTemplateFiles.put(<span class="hljs-string">"api.mustache"</span>, <span class="hljs-string">".zz"</span>);
|
||
embeddedTemplateDir = templateDir = <span class="hljs-string">"common-mark-documentation"</span>;
|
||
apiPackage = File.separator + <span class="hljs-string">"Apis"</span>;
|
||
modelPackage = File.separator + <span class="hljs-string">"Models"</span>;
|
||
supportingFiles.add(<span class="hljs-keyword">new</span> SupportingFile(<span class="hljs-string">"README.mustache"</span>, <span class="hljs-string">""</span>, <span class="hljs-string">"README.md"</span>));
|
||
<span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Fill this out.</span>
|
||
}
|
||
</code></pre>
|
||
<p>These options are some defaults which may require updating. Let's look line-by-line at the config.</p>
|
||
<pre><code class="hljs css language-java">outputFolder = <span class="hljs-string">"generated-code"</span> + File.separator + <span class="hljs-string">"common-mark"</span>;
|
||
</code></pre>
|
||
<p>This is the default output location. This will be <code>generated-code/common-mark</code> on non-Windows machines and <code>generated-code\common-mark</code> on Windows. You may change this to any value you'd like, but a user will almost always provide an output directory.</p>
|
||
<blockquote>
|
||
<p>When joining paths, always use <code>File.seperator</code></p>
|
||
</blockquote>
|
||
<pre><code class="hljs css language-java"> modelTemplateFiles.put(<span class="hljs-string">"model.mustache"</span>, <span class="hljs-string">".zz"</span>);
|
||
</code></pre>
|
||
<p>The <code>model.mustache</code> file is registered as the template for model generation. The <code>new.sh</code> script doesn't have a way to know your intended file extension, so we default to a <code>.zz</code> extension. This <em>must</em> be changed (unless your generator's target extension is <code>.zz</code>). For this example, you'd change <code>.zz</code> to <code>.md</code> or <code>.markdown</code>, depending on your preference.</p>
|
||
<p>This model template registration will use <code>model.mustache</code> to generate a new file for every model defined in your API's specification document.</p>
|
||
<p>The path is considered relative to <code>embeddedTemplateDir</code>, <code>templateDir</code>, or a library subdirectory (refer to the Java client generator implementation for a prime example).</p>
|
||
<pre><code class="hljs css language-java">apiTemplateFiles.put(<span class="hljs-string">"api.mustache"</span>, <span class="hljs-string">".zz"</span>);
|
||
</code></pre>
|
||
<p>This is the template used for generating API related files. Similar to the above model template, you'll want to change <code>.zz</code> to <code>.md</code> or <code>.markdown</code>.</p>
|
||
<p>The path is considered relative to <code>embeddedTemplateDir</code>, <code>templateDir</code>, or a library subdirectory (refer to the Java client generator implementation for a prime example).</p>
|
||
<pre><code class="hljs css language-java">embeddedTemplateDir = templateDir = <span class="hljs-string">"common-mark-documentation"</span>;
|
||
</code></pre>
|
||
<p>This line sets the embedded and template directories to <code>common-mark-documentation</code>. The <code>embeddedTemplateDir</code> refers to the directory which will exist under <code>modules/openapi-generator/src/main/resources</code> and will be published with every release in which your new generator is present.</p>
|
||
<p>The <code>templateDir</code> variable refers to the "current" template directory setting, as defined by the user. That is, the user may invoke with <code>-t</code> or <code>--template-directory</code> (or plugin option variants), and override this directory.</p>
|
||
<p>Both of these variables exist because the generator will fallback to files under <code>embeddedTemplateDir</code> if they are not defined in the user's custom template directory.</p>
|
||
<pre><code class="hljs css language-java">apiPackage = File.separator + <span class="hljs-string">"Apis"</span>;
|
||
</code></pre>
|
||
<p>This sets the "package" location for anything considered an API document. You might want to change this setting if, for instance, your language doesn't support uppercase letters in the path. We don't need to worry about that here.</p>
|
||
<p>Every templated output from <code>api.mustache</code> (registered via <code>apiTemplateFiles</code> above) will end up in the directory defined by <code>apiPackage</code> here.</p>
|
||
<pre><code class="hljs css language-java">modelPackage = File.separator + <span class="hljs-string">"Models"</span>;
|
||
</code></pre>
|
||
<p>Similarly, this sets the package for <code>Models</code>.</p>
|
||
<p>Every templated output from <code>model.mustache</code> (registered via <code>modelTemplateFiles</code> above) will end up in the directory defined by <code>modelPackage</code> here.</p>
|
||
<pre><code class="hljs css language-java">supportingFiles.add(<span class="hljs-keyword">new</span> SupportingFile(<span class="hljs-string">"README.mustache"</span>, <span class="hljs-string">""</span>, <span class="hljs-string">"README.md"</span>));
|
||
</code></pre>
|
||
<p>A "supporting file" is an extra file which isn't created once for every operation or model defined in your specification document. It is a single file which may or may not be templated (determined by the extension of the filename).</p>
|
||
<p>A supporting file only passes through the Mustache template processor if the filename ends in <code>.mustache</code>.</p>
|
||
<p>The path is considered relative to <code>embeddedTemplateDir</code>, <code>templateDir</code>, or a library subdirectory (refer to the Java client generator implementation for a prime example).</p>
|
||
<blockquote>
|
||
<p>If you want your readme to be generic (not templated), just rename the file to README.md and change <code>README.mustache</code> to <code>README.md</code> above.</p>
|
||
</blockquote>
|
||
<h3><a class="anchor" aria-hidden="true" id="create-templates"></a><a href="#create-templates" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Create templates</h3>
|
||
<p>The <code>new.sh</code> created our three required files. Let's start filling out each of these files.</p>
|
||
<h4><a class="anchor" aria-hidden="true" id="readmemustache"></a><a href="#readmemustache" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>README.mustache</h4>
|
||
<pre><code class="hljs css language-mustache"><span class="xml"># Documentation for </span><span class="hljs-template-variable">{{appName}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">generateApiDocs</span>}}</span><span class="xml">
|
||
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"documentation-for-api-endpoints"</span>></span><span class="hljs-tag"></<span class="hljs-name">a</span>></span>
|
||
## Documentation for API Endpoints
|
||
|
||
All URIs are relative to *</span><span class="hljs-template-variable">{{{basePath}}}</span><span class="xml">*
|
||
|
||
Class | Method | HTTP request | Description
|
||
------------ | ------------- | ------------- | -------------
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">apiInfo</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">apis</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">operations</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">operation</span>}}</span><span class="xml">*</span><span class="hljs-template-variable">{{classname}}</span><span class="xml">* | [**</span><span class="hljs-template-variable">{{operationId}}</span><span class="xml">**](Apis/</span><span class="hljs-template-variable">{{apiDocPath}}</span><span class="hljs-template-variable">{{classname}}</span><span class="xml">.md#</span><span class="hljs-template-variable">{{operationIdLowerCase}}</span><span class="xml">) | **</span><span class="hljs-template-variable">{{httpMethod}}</span><span class="xml">** </span><span class="hljs-template-variable">{{path}}</span><span class="xml"> | </span><span class="hljs-template-tag">{{#<span class="hljs-name">summary</span>}}</span><span class="hljs-template-variable">{{{summary}}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">summary</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">operation</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">operations</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">apis</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">apiInfo</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateApiDocs</span>}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">generateModelDocs</span>}}</span><span class="xml">
|
||
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"documentation-for-models"</span>></span><span class="hljs-tag"></<span class="hljs-name">a</span>></span>
|
||
## Documentation for Models
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">modelPackage</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">models</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">model</span>}}</span><span class="xml"> - [</span><span class="hljs-template-variable">{{{modelPackage}}}</span><span class="xml">.</span><span class="hljs-template-variable">{{{classname}}}</span><span class="xml">](Models/</span><span class="hljs-template-variable">{{modelDocPath}}</span><span class="hljs-template-variable">{{{classname}}}</span><span class="xml">.md)
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">model</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">models</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">modelPackage</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-variable">{{^modelPackage}}</span><span class="xml">
|
||
No model defined in this package
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">modelPackage</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateModelDocs</span>}}</span><span class="xml">
|
||
|
||
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"documentation-for-authorization"</span>></span><span class="hljs-tag"></<span class="hljs-name">a</span>></span></span><span class="hljs-comment">{{! <span class="hljs-doctag">TODO:</span> optional documentation for authorization? }}</span><span class="xml">
|
||
## Documentation for Authorization
|
||
|
||
</span><span class="hljs-template-variable">{{^authMethods}}</span><span class="xml">
|
||
All endpoints do not require authorization.
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">last</span>}}</span><span class="xml">
|
||
Authentication schemes defined for the API:
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">last</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{name}}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span><span class="hljs-tag"></<span class="hljs-name">a</span>></span>
|
||
### </span><span class="hljs-template-variable">{{name}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">isApiKey</span>}}</span><span class="xml">- **Type**: API key
|
||
- **API key parameter name**: </span><span class="hljs-template-variable">{{keyParamName}}</span><span class="xml">
|
||
- **Location**: </span><span class="hljs-template-tag">{{#<span class="hljs-name">isKeyInQuery</span>}}</span><span class="xml">URL query string</span><span class="hljs-template-tag">{{/<span class="hljs-name">isKeyInQuery</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">isKeyInHeader</span>}}</span><span class="xml">HTTP header</span><span class="hljs-template-tag">{{/<span class="hljs-name">isKeyInHeader</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">isApiKey</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">isBasic</span>}}</span><span class="xml">- **Type**: HTTP basic authentication
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">isBasic</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">isOAuth</span>}}</span><span class="xml">- **Type**: OAuth
|
||
- **Flow**: </span><span class="hljs-template-variable">{{flow}}</span><span class="xml">
|
||
- **Authorization URL**: </span><span class="hljs-template-variable">{{authorizationUrl}}</span><span class="xml">
|
||
- **Scopes**: </span><span class="hljs-template-variable">{{^scopes}}</span><span class="xml">N/A</span><span class="hljs-template-tag">{{/<span class="hljs-name">scopes</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">scopes</span>}}</span><span class="xml"> - </span><span class="hljs-template-variable">{{scope}}</span><span class="xml">: </span><span class="hljs-template-variable">{{description}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">scopes</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">isOAuth</span>}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
</span></code></pre>
|
||
<p>Let's not focus too much on the contents of this file. You may refer to <a href="/docs/templating">templating</a> for more details on the variables bound to these files and to <a href="/docs/debugging">debugging</a> how to debug the structures. Of note here is that we're generating structures in markdown as defined by the objects constructed by our new "Config" class.</p>
|
||
<h4><a class="anchor" aria-hidden="true" id="apimustache"></a><a href="#apimustache" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>api.mustache</h4>
|
||
<p>The API documentation might look like this:</p>
|
||
<pre><code class="hljs css language-mustache"><span class="xml"># </span><span class="hljs-template-variable">{{classname}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">description</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-variable">{{description}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">description</span>}}</span><span class="xml">
|
||
|
||
All URIs are relative to *</span><span class="hljs-template-variable">{{basePath}}</span><span class="xml">*
|
||
|
||
Method | HTTP request | Description
|
||
------------- | ------------- | -------------
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">operations</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">operation</span>}}</span><span class="xml">[**</span><span class="hljs-template-variable">{{operationId}}</span><span class="xml">**](</span><span class="hljs-template-variable">{{classname}}</span><span class="xml">.md#</span><span class="hljs-template-variable">{{operationId}}</span><span class="xml">) | **</span><span class="hljs-template-variable">{{httpMethod}}</span><span class="xml">** </span><span class="hljs-template-variable">{{path}}</span><span class="xml"> | </span><span class="hljs-template-tag">{{#<span class="hljs-name">summary</span>}}</span><span class="hljs-template-variable">{{summary}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">summary</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">operation</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">operations</span>}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">operations</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">operation</span>}}</span><span class="xml">
|
||
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{operationId}}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>></span><span class="hljs-tag"></<span class="hljs-name">a</span>></span>
|
||
# **</span><span class="hljs-template-variable">{{operationId}}</span><span class="xml">**
|
||
> </span><span class="hljs-template-tag">{{#<span class="hljs-name">returnType</span>}}</span><span class="hljs-template-variable">{{returnType}}</span><span class="xml"> </span><span class="hljs-template-tag">{{/<span class="hljs-name">returnType</span>}}</span><span class="hljs-template-variable">{{operationId}}</span><span class="xml">(</span><span class="hljs-template-tag">{{#<span class="hljs-name">allParams</span>}}</span><span class="hljs-template-variable">{{{paramName}}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">hasMore</span>}}</span><span class="xml">, </span><span class="hljs-template-tag">{{/<span class="hljs-name">hasMore</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">allParams</span>}}</span><span class="xml">)
|
||
|
||
</span><span class="hljs-template-variable">{{summary}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">notes</span>}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-variable">{{notes}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">notes</span>}}</span><span class="xml">
|
||
|
||
### Parameters
|
||
</span><span class="hljs-template-variable">{{^allParams}}</span><span class="xml">This endpoint does not need any parameter.</span><span class="hljs-template-tag">{{/<span class="hljs-name">allParams</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">allParams</span>}}</span><span class="hljs-template-tag">{{#-<span class="hljs-name">last</span>}}</span><span class="xml">
|
||
Name | Type | Description | Notes
|
||
------------- | ------------- | ------------- | -------------</span><span class="hljs-template-tag">{{/-<span class="hljs-name">last</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">allParams</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">allParams</span>}}</span><span class="xml"> **</span><span class="hljs-template-variable">{{paramName}}</span><span class="xml">** | </span><span class="hljs-template-tag">{{#<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="hljs-template-variable">{{^isPrimitiveType}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">isFile</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">isFile</span>}}</span><span class="hljs-template-variable">{{^isFile}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">generateModelDocs</span>}}</span><span class="xml">[**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**](</span><span class="hljs-template-variable">{{baseType}}</span><span class="xml">.md)</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateModelDocs</span>}}</span><span class="hljs-template-variable">{{^generateModelDocs}}</span><span class="xml">**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateModelDocs</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">isFile</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml">| </span><span class="hljs-template-variable">{{description}}</span><span class="xml"> |</span><span class="hljs-template-variable">{{^required}}</span><span class="xml"> [optional]</span><span class="hljs-template-tag">{{/<span class="hljs-name">required</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">defaultValue</span>}}</span><span class="xml"> [default to </span><span class="hljs-template-variable">{{defaultValue}}</span><span class="xml">]</span><span class="hljs-template-tag">{{/<span class="hljs-name">defaultValue</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">allowableValues</span>}}</span><span class="xml"> [enum: </span><span class="hljs-template-tag">{{#<span class="hljs-name">values</span>}}</span><span class="hljs-template-variable">{{{.}}}</span><span class="hljs-template-variable">{{^-last}}</span><span class="xml">, </span><span class="hljs-template-tag">{{/-<span class="hljs-name">last</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">values</span>}}</span><span class="xml">]</span><span class="hljs-template-tag">{{/<span class="hljs-name">allowableValues</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">allParams</span>}}</span><span class="xml">
|
||
|
||
### Return type
|
||
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">returnType</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">returnTypeIsPrimitive</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{returnType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">returnTypeIsPrimitive</span>}}</span><span class="hljs-template-variable">{{^returnTypeIsPrimitive}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">generateModelDocs</span>}}</span><span class="xml">[**</span><span class="hljs-template-variable">{{returnType}}</span><span class="xml">**](</span><span class="hljs-template-variable">{{returnBaseType}}</span><span class="xml">.md)</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateModelDocs</span>}}</span><span class="hljs-template-variable">{{^generateModelDocs}}</span><span class="xml">**</span><span class="hljs-template-variable">{{returnType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">generateModelDocs</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">returnTypeIsPrimitive</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">returnType</span>}}</span><span class="hljs-template-variable">{{^returnType}}</span><span class="xml">null (empty response body)</span><span class="hljs-template-tag">{{/<span class="hljs-name">returnType</span>}}</span><span class="xml">
|
||
|
||
### Authorization
|
||
|
||
</span><span class="hljs-template-variable">{{^authMethods}}</span><span class="xml">No authorization required</span><span class="hljs-template-tag">{{/<span class="hljs-name">authMethods</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">authMethods</span>}}</span><span class="xml">[</span><span class="hljs-template-variable">{{name}}</span><span class="xml">](../README.md#</span><span class="hljs-template-variable">{{name}}</span><span class="xml">)</span><span class="hljs-template-variable">{{^-last}}</span><span class="xml">, </span><span class="hljs-template-tag">{{/-<span class="hljs-name">last</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">authMethods</span>}}</span><span class="xml">
|
||
|
||
### HTTP request headers
|
||
|
||
- **Content-Type**: </span><span class="hljs-template-tag">{{#<span class="hljs-name">consumes</span>}}</span><span class="hljs-template-variable">{{{mediaType}}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">hasMore</span>}}</span><span class="xml">, </span><span class="hljs-template-tag">{{/<span class="hljs-name">hasMore</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">consumes</span>}}</span><span class="hljs-template-variable">{{^consumes}}</span><span class="xml">Not defined</span><span class="hljs-template-tag">{{/<span class="hljs-name">consumes</span>}}</span><span class="xml">
|
||
- **Accept**: </span><span class="hljs-template-tag">{{#<span class="hljs-name">produces</span>}}</span><span class="hljs-template-variable">{{{mediaType}}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">hasMore</span>}}</span><span class="xml">, </span><span class="hljs-template-tag">{{/<span class="hljs-name">hasMore</span>}}</span><span class="hljs-template-tag">{{/<span class="hljs-name">produces</span>}}</span><span class="hljs-template-variable">{{^produces}}</span><span class="xml">Not defined</span><span class="hljs-template-tag">{{/<span class="hljs-name">produces</span>}}</span><span class="xml">
|
||
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">operation</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">operations</span>}}</span><span class="xml">
|
||
|
||
</span></code></pre>
|
||
<h4><a class="anchor" aria-hidden="true" id="modelmustache"></a><a href="#modelmustache" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>model.mustache</h4>
|
||
<p>The models file could resemble the following.</p>
|
||
<pre><code class="hljs css language-mustache"><span class="hljs-template-tag">{{#<span class="hljs-name">models</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">model</span>}}</span><span class="xml">
|
||
# </span><span class="hljs-template-variable">{{{packageName}}}</span><span class="xml">.</span><span class="hljs-template-variable">{{modelPackage}}</span><span class="xml">.</span><span class="hljs-template-variable">{{{classname}}}</span><span class="xml">
|
||
## Properties
|
||
|
||
Name | Type | Description | Notes
|
||
------------ | ------------- | ------------- | -------------
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">parent</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">parentVars</span>}}</span><span class="xml">
|
||
**</span><span class="hljs-template-variable">{{name}}</span><span class="xml">** | </span><span class="hljs-template-tag">{{#<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="hljs-template-variable">{{^isPrimitiveType}}</span><span class="xml">[**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**](</span><span class="hljs-template-variable">{{complexType}}</span><span class="xml">.md)</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml"> | </span><span class="hljs-template-variable">{{description}}</span><span class="xml"> | </span><span class="hljs-template-variable">{{^required}}</span><span class="xml">[optional] </span><span class="hljs-template-tag">{{/<span class="hljs-name">required</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">readOnly</span>}}</span><span class="xml">[readonly] </span><span class="hljs-template-tag">{{/<span class="hljs-name">readOnly</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">defaultValue</span>}}</span><span class="xml">[default to </span><span class="hljs-template-variable">{{{.}}}</span><span class="xml">]</span><span class="hljs-template-tag">{{/<span class="hljs-name">defaultValue</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">parentVars</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">parent</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{#<span class="hljs-name">vars</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{name}}</span><span class="xml">** | </span><span class="hljs-template-tag">{{#<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml">**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="hljs-template-variable">{{^isPrimitiveType}}</span><span class="xml">[**</span><span class="hljs-template-variable">{{dataType}}</span><span class="xml">**](</span><span class="hljs-template-variable">{{complexType}}</span><span class="xml">.md)</span><span class="hljs-template-tag">{{/<span class="hljs-name">isPrimitiveType</span>}}</span><span class="xml"> | </span><span class="hljs-template-variable">{{description}}</span><span class="xml"> | </span><span class="hljs-template-variable">{{^required}}</span><span class="xml">[optional] </span><span class="hljs-template-tag">{{/<span class="hljs-name">required</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">readOnly</span>}}</span><span class="xml">[readonly] </span><span class="hljs-template-tag">{{/<span class="hljs-name">readOnly</span>}}</span><span class="hljs-template-tag">{{#<span class="hljs-name">defaultValue</span>}}</span><span class="xml">[default to </span><span class="hljs-template-variable">{{{.}}}</span><span class="xml">]</span><span class="hljs-template-tag">{{/<span class="hljs-name">defaultValue</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">vars</span>}}</span><span class="xml">
|
||
|
||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">model</span>}}</span><span class="xml">
|
||
</span><span class="hljs-template-tag">{{/<span class="hljs-name">models</span>}}</span><span class="xml">
|
||
</span></code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" id="build-it"></a><a href="#build-it" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Build it</h3>
|
||
<p>To compile quickly to test this out, you can run <code>mvn clean package -DskipTests</code>.</p>
|
||
<blockquote>
|
||
<p>When implementing a more robust generator, you'll want to run all tests as well: <code>mvn clean package</code></p>
|
||
</blockquote>
|
||
<h3><a class="anchor" aria-hidden="true" id="compile-sample"></a><a href="#compile-sample" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Compile Sample</h3>
|
||
<p>The <code>new.sh</code> script created <code>bin/common-mark-documentation-petstore.sh</code>:</p>
|
||
<pre><code class="hljs css language-bash"><span class="hljs-meta">#!/bin/sh
|
||
</span>
|
||
SCRIPT=<span class="hljs-string">"<span class="hljs-variable">$0</span>"</span>
|
||
|
||
<span class="hljs-keyword">while</span> [ -h <span class="hljs-string">"<span class="hljs-variable">$SCRIPT</span>"</span> ] ; <span class="hljs-keyword">do</span>
|
||
ls=$(ls -ld <span class="hljs-string">"<span class="hljs-variable">$SCRIPT</span>"</span>)
|
||
link=$(expr <span class="hljs-string">"<span class="hljs-variable">$ls</span>"</span> : <span class="hljs-string">'.*-> \(.*\)$'</span>)
|
||
<span class="hljs-keyword">if</span> expr <span class="hljs-string">"<span class="hljs-variable">$link</span>"</span> : <span class="hljs-string">'/.*'</span> > /dev/null; <span class="hljs-keyword">then</span>
|
||
SCRIPT=<span class="hljs-string">"<span class="hljs-variable">$link</span>"</span>
|
||
<span class="hljs-keyword">else</span>
|
||
SCRIPT=$(dirname <span class="hljs-string">"<span class="hljs-variable">$SCRIPT</span>"</span>)/<span class="hljs-string">"<span class="hljs-variable">$link</span>"</span>
|
||
<span class="hljs-keyword">fi</span>
|
||
<span class="hljs-keyword">done</span>
|
||
|
||
<span class="hljs-keyword">if</span> [ ! -d <span class="hljs-string">"<span class="hljs-variable">${APP_DIR}</span>"</span> ]; <span class="hljs-keyword">then</span>
|
||
APP_DIR=$(dirname <span class="hljs-string">"<span class="hljs-variable">$SCRIPT</span>"</span>)/..
|
||
APP_DIR=$(<span class="hljs-built_in">cd</span> <span class="hljs-string">"<span class="hljs-variable">${APP_DIR}</span>"</span>; <span class="hljs-built_in">pwd</span>)
|
||
<span class="hljs-keyword">fi</span>
|
||
|
||
executable=<span class="hljs-string">"./modules/openapi-generator-cli/target/openapi-generator-cli.jar"</span>
|
||
|
||
<span class="hljs-keyword">if</span> [ ! -f <span class="hljs-string">"<span class="hljs-variable">$executable</span>"</span> ]
|
||
<span class="hljs-keyword">then</span>
|
||
mvn clean package
|
||
<span class="hljs-keyword">fi</span>
|
||
|
||
<span class="hljs-comment"># if you've executed sbt assembly previously it will use that instead.</span>
|
||
<span class="hljs-built_in">export</span> JAVA_OPTS=<span class="hljs-string">"<span class="hljs-variable">${JAVA_OPTS}</span> -Xmx1024M -DloggerPath=conf/log4j.properties"</span>
|
||
ags=<span class="hljs-string">"<span class="hljs-variable">$@</span> generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g common-mark -o samples/documentation/petstore/common/mark"</span>
|
||
|
||
java <span class="hljs-variable">${JAVA_OPTS}</span> -jar <span class="hljs-variable">${executable}</span> <span class="hljs-variable">${ags}</span>
|
||
</code></pre>
|
||
<p>This script is often used to apply default options for generation. A common option in most of these script is to define the template directory as the generator's directory under <code>resources</code>. This allows template maintainers to modify and test out template changes which don't require recompilation of the entire project. You'd still need to recompile the project in full if you add or modify behaviors to the generator (such as adding a <code>CliOption</code>).</p>
|
||
<p>Add <code>-t modules/openapi-generator/src/main/resources/common-mark-documentation</code> to <code>ags</code> line to simplify the evaluation of template-only modifications:</p>
|
||
<pre><code class="hljs css language-diff">diff --git a/bin/markdown-documentation-petstore.sh b/bin/markdown-documentation-petstore.sh
|
||
index d816771478..94b4ce6d12 100644
|
||
<span class="hljs-comment">--- a/bin/markdown-documentation-petstore.sh</span>
|
||
<span class="hljs-comment">+++ b/bin/markdown-documentation-petstore.sh</span>
|
||
@@ -26,6 +26,6 @@ fi
|
||
|
||
# if you've executed sbt assembly previously it will use that instead.
|
||
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||
<span class="hljs-deletion">-ags="$@ generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g common-mark -o samples/documentation/petstore/common-mark"</span>
|
||
<span class="hljs-addition">+ags="$@ generate -t modules/openapi-generator/src/main/resources/common-mark-documentation -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g common-mark -o samples/documentation/petstore/common/markdown"</span>
|
||
|
||
java ${JAVA_OPTS} -jar ${executable} ${ags}
|
||
</code></pre>
|
||
<h3><a class="anchor" aria-hidden="true" id="verify-output"></a><a href="#verify-output" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Verify output</h3>
|
||
<p>Creating a new generator will be an iterative task. Once you've generated the sample, you'll want to try it out. For compiled client/server outputs, this would mean running the code or creating a small sample project to consume your artifact just to make sure it works.</p>
|
||
<p>For markdown, you can open in Visual Studio Code or any other editor with a markdown preview. Not all editors support relative links to other markdown documents. To test the output in this guide, install <code>markserv</code>:</p>
|
||
<pre><code class="hljs css language-bash">npm install --global markserv
|
||
</code></pre>
|
||
<p>Now, you can serve the output directory directly and test your links:</p>
|
||
<pre><code class="hljs css language-bash">markserv samples/documentation/petstore/common/markdown
|
||
</code></pre>
|
||
<p>That's it! You've created your first generator!</p>
|
||
</span></div></article></div><div class="docLastUpdate"><em>Last updated on 1/20/2020</em></div><div class="docs-prevnext"><a class="docs-prev button" href="/docs/contribute-building"><span class="arrow-prev">← </span><span>Building the code</span></a><a class="docs-next button" href="/docs/roadmap"><span>Roadmap</span><span class="arrow-next"> →</span></a></div></div></div><nav class="onPageNav"><ul class="toc-headings"><li><a href="#required-files">Required Files</a></li><li><a href="#newsh">new.sh</a><ul class="toc-headings"><li><a href="#review-generated-config">Review Generated Config</a></li><li><a href="#create-templates">Create templates</a></li><li><a href="#build-it">Build it</a></li><li><a href="#compile-sample">Compile Sample</a></li><li><a href="#verify-output">Verify output</a></li></ul></li></ul></nav></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/" class="nav-home"><img src="/img/mono-logo.svg" alt="OpenAPI Generator" width="66" height="58"/></a><div><h5>Docs</h5><a href="/docs/en/customization.html">Customizing Generators</a><a href="/docs/en/integrations.html">Workflow Integrations</a></div><div><h5>Community</h5><a href="/en/users.html">User Showcase</a><a href="http://stackoverflow.com/questions/tagged/openapi-generator" target="_blank" rel="noreferrer noopener">Stack Overflow</a><a href="https://join.slack.com/t/openapi-generator/shared_invite/enQtNzAyNDMyOTU0OTE1LTY5ZDBiNDI5NzI5ZjQ1Y2E5OWVjMjZkYzY1ZGM2MWQ4YWFjMzcyNDY5MGI4NjQxNDBiMTlmZTc5NjY2ZTQ5MGM">Chat Room</a><a href="https://twitter.com/oas_generator" target="_blank" rel="noreferrer noopener">Twitter</a></div><div><h5>More</h5><a href="/blog">Blog</a><a href="https://github.com/OpenAPITools/openapi-generator">GitHub Repo</a><a class="github-button" href="https://github.com/OpenAPITools/openapi-generator" data-icon="octicon-star" data-count-href="/OpenAPITools/openapi-generator/stargazers" data-show-count="true" data-count-aria-label="# stargazers on GitHub" aria-label="Star this project on GitHub">Star</a></div></section><section class="copyright">Copyright © 2020 OpenAPI-Generator Contributors (https://openapi-generator.tech). (Both "OpenAPI Tools" (https://OpenAPITools.org) and "OpenAPI Generator" are not affiliated with OpenAPI Initiative (OAI))</section></footer></div></body></html> |