Issue #214 Added support for page breaks (#226)

* Added support for page breaks
* Added documentation and config file support for page breaks and regex
This commit is contained in:
Cas Eliëns
2017-01-03 11:21:31 +01:00
committed by Robert Winkler
parent 76c54a713a
commit 2f33522e6d
14 changed files with 1295 additions and 33 deletions

View File

@@ -114,4 +114,12 @@
* Issue #205: Fixed the option to influence resource ordering
* Issue #198: Chinese chinese language encoding
* Issue #207: Properties that start with an underscore are displayed correctly now
* Refactored Swagger2Markup to use a Component-Based design. A document can be composed of components and components can be composed of other components.
* Refactored Swagger2Markup to use a Component-Based design. A document can be composed of components and components can be composed of other components.
=== Version 1.1.2
* Issue #214: Add page break locations
* Issue #223: Improve example rendering
* Issue #215: Add ability to group operations by RegEx
* Added new configuration options: pageBreakLocations, headerRegex
* Added new valid value for configuration headerRegex: REGEX
* Updated markup-document-builder from 1.1.0 to 1.1.1-SNAPSHOT

View File

@@ -13,7 +13,7 @@ buildscript {
}
}
description = 'swagger2markup Build'
version = '1.1.2-SNAPSHOT'
version = '1.2.0'
ext.releaseVersion = '1.1.1'
group = 'io.github.swagger2markup'
@@ -41,7 +41,7 @@ repositories {
}
dependencies {
compile 'io.github.swagger2markup:markup-document-builder:1.1.0'
compile 'io.github.swagger2markup:markup-document-builder:1.1.1-SNAPSHOT'
compile 'io.swagger:swagger-compat-spec-parser:1.0.23'
compile 'org.apache.commons:commons-configuration2:2.1'
compile 'commons-beanutils:commons-beanutils:1.9.2'

View File

@@ -136,7 +136,7 @@ The following tables list all available properties of Swagger2Markup:
|Name | Description | Possible Values | Default
|swagger2markup.markupLanguage| Specifies the markup language which should be used to generate the files. | ASCIIDOC, MARKDOWN, CONFLUENCE_MARKUP | ASCIIDOC
|swagger2markup.swaggerMarkupLanguage| Specifies the markup language used in Swagger descriptions. | ASCIIDOC, MARKDOWN, CONFLUENCE_MARKUP | MARKDOWN
|swagger2markup.pathsGroupedBy| Specifies how the paths should be grouped | AS_IS, TAGS | AS_IS
|swagger2markup.pathsGroupedBy| Specifies how the paths should be grouped | AS_IS, TAGS, REGEX | AS_IS
|swagger2markup.outputLanguage| Specifies the language of the labels | EN, DE, FR, RU | EN
|swagger2markup.lineSeparator| Specifies the line separator which should be used | UNIX, WINDOWS, MAC | <System-dependent>
|swagger2markup.generatedExamplesEnabled| Specifies if HTTP request and response examples should be generated | true, false | false
@@ -144,6 +144,7 @@ The following tables list all available properties of Swagger2Markup:
|swagger2markup.pathSecuritySectionEnabled| Optionally disable the security section for path sections | true, false | true
|swagger2markup.anchorPrefix| Optionally prefix all anchors for uniqueness if you want to include generated documents into a global documentation | Any String |
|swagger2markup.basePathPrefixEnabled| Prepend the basePath to all paths | true, false | false
|swagger2markup.headerRegex | Regular expression to use when grouping by RegEx | Any valid RegEx pattern with at least one capture group |
|===
[options="header"]
@@ -193,6 +194,13 @@ The following tables list all available properties of Swagger2Markup:
|swagger2markup.inlineSchemaEnabled| Enable inline object schema support | true, false | true
|===
[options="header"]
.Properties which configure page breaking
|===
|Name | Description | Possible Values | Default
|swagger2markup.pageBreakLocations | Specifies where page breaks should be inserted. | BEFORE_OPERATION, BEFORE_OPERATION_DESCRIPTION, BEFORE_OPERATION_PARAMETERS, BEFORE_OPERATION_RESPONSES, BEFORE_OPERATION_CONSUMES, BEFORE_OPERATION_PRODUCES, BEFORE_OPERATION_EXAMPLE_REQUEST, BEFORE_OPERATION_EXAMPLE_RESPONSE, BEFORE_DEFINITION, AFTER_OPERATION, AFTER_OPERATION_DESCRIPTION, AFTER_OPERATION_PARAMETERS, AFTER_OPERATION_RESPONSES, AFTER_OPERATION_CONSUMES, AFTER_OPERATION_PRODUCES, AFTER_OPERATION_EXAMPLE_REQUEST, AFTER_OPERATION_EXAMPLE_RESPONSE, AFTER_DEFINITION | empty
|===
=== Logging
Swagger2Markup uses http://www.slf4j.org/[SLF4J] for all internal logging, but leaves the underlying log implementation open. To change the log level, you have the set the log level of the `io.github.swagger2markup` package.

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup;
public enum PageBreakLocations {
BEFORE_OPERATION,
BEFORE_OPERATION_DESCRIPTION,
BEFORE_OPERATION_PARAMETERS,
BEFORE_OPERATION_RESPONSES,
BEFORE_OPERATION_CONSUMES,
BEFORE_OPERATION_PRODUCES,
BEFORE_OPERATION_EXAMPLE_REQUEST,
BEFORE_OPERATION_EXAMPLE_RESPONSE,
BEFORE_DEFINITION,
AFTER_OPERATION,
AFTER_OPERATION_DESCRIPTION,
AFTER_OPERATION_PARAMETERS,
AFTER_OPERATION_RESPONSES,
AFTER_OPERATION_CONSUMES,
AFTER_OPERATION_PRODUCES,
AFTER_OPERATION_EXAMPLE_REQUEST,
AFTER_OPERATION_EXAMPLE_RESPONSE,
AFTER_DEFINITION
}

View File

@@ -21,6 +21,7 @@ import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.parameters.Parameter;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
/**
@@ -219,4 +220,11 @@ public interface Swagger2MarkupConfig {
* @return the extension properties
*/
Swagger2MarkupProperties getExtensionsProperties();
/**
* Returns the list of page break locations
*
* @return List of PageBreakLocations
*/
List<PageBreakLocations> getPageBreakLocations();
}

View File

@@ -25,10 +25,8 @@ import org.apache.commons.configuration2.MapConfiguration;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
import java.util.regex.Pattern;
public class Swagger2MarkupProperties {
@@ -65,6 +63,7 @@ public class Swagger2MarkupProperties {
public static final String PROPERTY_ORDER_BY = PROPERTIES_PREFIX + ".propertyOrderBy";
public static final String RESPONSE_ORDER_BY = PROPERTIES_PREFIX + ".responseOrderBy";
public static final String LINE_SEPARATOR = PROPERTIES_PREFIX + ".lineSeparator";
public static final String PAGE_BREAK_LOCATIONS = PROPERTIES_PREFIX + ".pageBreakLocations";
/**
* Prefix for Swagger2Markup extension properties
@@ -337,4 +336,20 @@ public class Swagger2MarkupProperties {
public List<String> getKeys(String prefix) {
return IteratorUtils.toList(configuration.getKeys(prefix));
}
public List<PageBreakLocations> getPageBreakLocations(String key) {
List result = configuration.getList(PageBreakLocations.class, key);
if(result == null) result = new ArrayList<PageBreakLocations>();
return result;
}
public Optional<Pattern> getHeaderPattern(String key) {
Optional<String> property = getString(key);
if (property.isPresent()) {
return Optional.of(Pattern.compile(property.get()));
} else {
return Optional.empty();
}
}
}

View File

@@ -30,10 +30,7 @@ import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -107,6 +104,12 @@ public class Swagger2MarkupConfigBuilder {
config.lineSeparator = LineSeparator.valueOf(lineSeparator.get());
}
config.pageBreakLocations = swagger2MarkupProperties.getPageBreakLocations(PAGE_BREAK_LOCATIONS);
Optional<Pattern> headerPattern = swagger2MarkupProperties.getHeaderPattern(HEADER_REGEX);
config.headerPattern = headerPattern.orElse(null);
Configuration swagger2markupConfiguration = compositeConfiguration.subset(PROPERTIES_PREFIX);
Configuration extensionsConfiguration = swagger2markupConfiguration.subset(EXTENSION_PREFIX);
config.extensionsProperties = new Swagger2MarkupProperties(extensionsConfiguration);
@@ -486,11 +489,23 @@ public class Swagger2MarkupConfigBuilder {
* @return this builder
*/
public Swagger2MarkupConfigBuilder withAnchorPrefix(String anchorPrefix) {
Validate.notNull(anchorPrefix, "%s must no be null", "anchorPrefix");
Validate.notNull(anchorPrefix, "%s must not be null", "anchorPrefix");
config.anchorPrefix = anchorPrefix;
return this;
}
/**
* Set the page break locations
*
* @param locations List of locations to create new pages
* @return this builder
*/
public Swagger2MarkupConfigBuilder withPageBreaks(List<PageBreakLocations> locations) {
Validate.notNull(locations, "%s must not be null", "locations");
config.pageBreakLocations = locations;
return this;
}
/**
* Specifies the line separator which should be used.
*
@@ -540,6 +555,8 @@ public class Swagger2MarkupConfigBuilder {
private String separatedOperationsFolder;
private String separatedDefinitionsFolder;
private List<PageBreakLocations> pageBreakLocations;
private Pattern headerPattern;
private Swagger2MarkupProperties extensionsProperties;
@@ -718,5 +735,10 @@ public class Swagger2MarkupConfigBuilder {
public boolean isBasePathPrefixEnabled() {
return basePathPrefixEnabled;
}
@Override
public List<PageBreakLocations> getPageBreakLocations() {
return pageBreakLocations;
}
}
}

View File

@@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.PageBreakLocations;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
@@ -41,6 +42,7 @@ import org.apache.commons.lang3.math.NumberUtils;
import java.util.*;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.PageBreakLocations.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Position;
@@ -80,21 +82,46 @@ public class PathOperationComponent extends MarkupComponent<PathOperationCompone
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
List<PageBreakLocations> locations = config.getPageBreakLocations();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_BEFORE, markupDocBuilder, operation));
if (locations.contains(BEFORE_OPERATION)) markupDocBuilder.pageBreak();
buildOperationTitle(markupDocBuilder, operation);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_BEGIN, markupDocBuilder, operation));
buildDeprecatedSection(markupDocBuilder, operation);
if (locations.contains(BEFORE_OPERATION_DESCRIPTION)) markupDocBuilder.pageBreak();
buildDescriptionSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_DESCRIPTION)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_PARAMETERS)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildParametersSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(AFTER_OPERATION_PARAMETERS)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildBodyParameterSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(BEFORE_OPERATION_RESPONSES)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildResponsesSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(AFTER_OPERATION_RESPONSES)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_CONSUMES)) markupDocBuilder.pageBreak();
buildConsumesSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_CONSUMES)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_PRODUCES)) markupDocBuilder.pageBreak();
buildProducesSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_PRODUCES)) markupDocBuilder.pageBreak();
buildTagsSection(markupDocBuilder, operation);
buildSecuritySchemeSection(markupDocBuilder, operation);
buildExamplesSection(markupDocBuilder, operation);
buildExamplesSection(markupDocBuilder, operation, locations);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_END, markupDocBuilder, operation));
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_AFTER, markupDocBuilder, operation));
if (locations.contains(AFTER_OPERATION)) markupDocBuilder.pageBreak();
return markupDocBuilder;
}
@@ -317,17 +344,23 @@ public class PathOperationComponent extends MarkupComponent<PathOperationCompone
*
* @param operation the Swagger Operation
*/
private void buildExamplesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
private void buildExamplesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation, List<PageBreakLocations> locations) {
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
exampleMap(markupDocBuilder, generatedRequestExampleMap, labels.getLabel(EXAMPLE_REQUEST), labels.getLabel(REQUEST));
exampleMap(markupDocBuilder, generatedResponseExampleMap, labels.getLabel(EXAMPLE_RESPONSE), labels.getLabel(RESPONSE));
boolean beforeExampleRequestBreak = locations.contains(BEFORE_OPERATION_EXAMPLE_REQUEST);
boolean afterExampleRequestBreak = locations.contains(AFTER_OPERATION_EXAMPLE_REQUEST);
boolean beforeExampleResponseBreak = locations.contains(BEFORE_OPERATION_EXAMPLE_RESPONSE);
boolean afterExampleResponseBreak = locations.contains(AFTER_OPERATION_EXAMPLE_RESPONSE);
exampleMap(markupDocBuilder, generatedRequestExampleMap, labels.getLabel(EXAMPLE_REQUEST), labels.getLabel(REQUEST), beforeExampleRequestBreak, afterExampleRequestBreak);
exampleMap(markupDocBuilder, generatedResponseExampleMap, labels.getLabel(EXAMPLE_RESPONSE), labels.getLabel(RESPONSE), beforeExampleResponseBreak, afterExampleResponseBreak);
}
private void exampleMap(MarkupDocBuilder markupDocBuilder, Map<String, Object> exampleMap, String operationSectionTitle, String sectionTitle) {
private void exampleMap(MarkupDocBuilder markupDocBuilder, Map<String, Object> exampleMap, String operationSectionTitle, String sectionTitle, boolean beforeBreak, boolean afterBreak) {
if (exampleMap.size() > 0) {
if (beforeBreak) markupDocBuilder.pageBreak();
buildSectionTitle(markupDocBuilder, operationSectionTitle);
for (Map.Entry<String, Object> entry : exampleMap.entrySet()) {
@@ -376,6 +409,7 @@ public class PathOperationComponent extends MarkupComponent<PathOperationCompone
markupDocBuilder.listingBlock(Json.pretty(entry.getValue()), "json");
}
}
if (afterBreak) markupDocBuilder.pageBreak();
}
}

View File

@@ -18,6 +18,7 @@ package io.github.swagger2markup.internal.document;
import com.google.common.collect.Multimap;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.component.PathOperationComponent;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverFromOperation;
@@ -68,22 +69,16 @@ public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
this.operationDocumentNameResolver = new OperationDocumentNameResolver(context);
this.operationDocumentResolverDefault = new OperationDocumentResolverDefault(context);
if (config.isGeneratedExamplesEnabled()) {
if (logger.isDebugEnabled()) {
if (logger.isDebugEnabled()) {
if (config.isGeneratedExamplesEnabled()) {
logger.debug("Generate examples is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
} else {
logger.debug("Generate examples is disabled.");
}
}
if (config.isSeparatedOperationsEnabled()) {
if (logger.isDebugEnabled()) {
if (config.isSeparatedOperationsEnabled()) {
logger.debug("Create separated operation files is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
} else {
logger.debug("Create separated operation files is disabled.");
}
}
@@ -121,7 +116,7 @@ public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
List<PathOperation> pathOperations = PathUtils.toPathOperationsList(paths, getBasePath(), config.getOperationOrdering());
if (CollectionUtils.isNotEmpty(pathOperations)) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
pathOperations.forEach(operation -> buildOperation(markupDocBuilder, operation));
pathOperations.forEach(operation -> buildOperation(markupDocBuilder, operation, config));
} else if (config.getPathsGroupedBy() == GroupBy.TAGS) {
Validate.notEmpty(context.getSwagger().getTags(), "Tags must not be empty, when operations are grouped by tags");
// Group operations by tag
@@ -135,7 +130,7 @@ public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
if (StringUtils.isNotBlank(description)) {
markupDocBuilder.paragraph(description);
}
operationsGroupedByTag.get(tagName).forEach(operation -> buildOperation(markupDocBuilder, operation));
operationsGroupedByTag.get(tagName).forEach(operation -> buildOperation(markupDocBuilder, operation, config));
});
} else if (config.getPathsGroupedBy() == GroupBy.REGEX) {
@@ -148,7 +143,7 @@ public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
for (String header : sortedHeaders) {
markupDocBuilder.sectionTitleWithAnchorLevel2(WordUtils.capitalize(header), header + "_resource");
operationsGroupedByRegex.get(header).forEach(operation -> buildOperation(markupDocBuilder, operation));
operationsGroupedByRegex.get(header).forEach(operation -> buildOperation(markupDocBuilder, operation, config));
}
}
}
@@ -197,7 +192,7 @@ public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
*
* @param operation operation
*/
private void buildOperation(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
private void buildOperation(MarkupDocBuilder markupDocBuilder, PathOperation operation, Swagger2MarkupConfig config) {
if (config.isSeparatedOperationsEnabled()) {
MarkupDocBuilder pathDocBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyPathOperationComponent(pathDocBuilder, operation);

View File

@@ -760,4 +760,29 @@ public class AsciidocConverterTest {
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/format").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithFormat.html");
}
@Test
public void testWithPageBreaks() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/test/asciidoc/page_breaks");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withoutInlineSchema()
.withPageBreaks(new ArrayList<>(asList(PageBreakLocations.BEFORE_OPERATION, PageBreakLocations.BEFORE_OPERATION_EXAMPLE_REQUEST)))
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/page_breaks").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithPageBreaks.html");
}
}

View File

@@ -0,0 +1,132 @@
[[_definitions]]
== Definitions
[[_category]]
=== Category
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|**id** +
__optional__|**Example** : `123`|integer(int64)
|**name** +
__optional__|**Example** : `"Canines"`|string
|===
[[_complexobject]]
=== ComplexObject
[options="header", cols=".^3,.^4"]
|===
|Name|Schema
|**subObject** +
__optional__|object
|===
[[_identified]]
=== Identified
[options="header", cols=".^3,.^4"]
|===
|Name|Schema
|**id** +
__optional__|integer(int64)
|===
[[_order]]
=== Order
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|**complete** +
__optional__||boolean
|**id** +
__optional__|**Example** : `77`|integer(int64)
|**petId** +
__optional__||integer(int64)
|**quantity** +
__optional__||integer(int32)
|**shipDate** +
__optional__||string(date-time)
|**status** +
__optional__|Order Status +
**Example** : `"DONE"`|string
|===
[[_pet]]
=== Pet
Test description
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|**category** +
__optional__||<<_category,Category>>
|**id** +
__optional__||integer(int64)
|**name** +
__required__|**Example** : `"doggie"`|string
|**nicknames** +
__optional__||< string, string > map
|**photoUrls** +
__required__||< string > array
|**status** +
__optional__|pet status in the store|string
|**tags** +
__optional__||< <<_tag,Tag>> > array
|**weight** +
__optional__|the weight of the pet|number
|===
[[_tag]]
=== Tag
[options="header", cols=".^3,.^4"]
|===
|Name|Schema
|**id** +
__optional__|integer(int64)
|**name** +
__optional__|string
|===
[[_user]]
=== User
[%hardbreaks]
__Polymorphism__ : Composition
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|**email** +
__optional__||string
|**firstName** +
__optional__||string
|**id** +
__optional__||integer(int64)
|**lastName** +
__optional__||string
|**password** +
__optional__||string
|**phone** +
__optional__||string
|**pictures** +
__optional__||< string(byte) > array
|**userStatus** +
__optional__|User Status|integer(int32)
|**username** +
__optional__||string
|===

View File

@@ -0,0 +1,44 @@
= Swagger Petstore API
[[_overview]]
== Overview
This is a sample server Petstore server.
http://swagger.wordnik.com[Learn about Swagger] or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
[%hardbreaks]
__Version__ : 1.0.0
=== Contact information
[%hardbreaks]
__Contact__ : apiteam@wordnik.com
=== License information
[%hardbreaks]
__License__ : Apache 2.0
__License URL__ : http://www.apache.org/licenses/LICENSE-2.0.html
__Terms of service__ : http://helloreverb.com/terms/
=== URI scheme
[%hardbreaks]
__Host__ : petstore.swagger.wordnik.com
__BasePath__ : /v2
__Schemes__ : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -0,0 +1,905 @@
[[_paths]]
== Paths
<<<
[[_addpet]]
=== Add a new pet to the store
....
POST /pets
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|Pet object that needs to be added to the store|<<_pet,Pet>>
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**405**|Invalid input|No Content
|===
==== Consumes
* `application/json`
* `application/xml`
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
==== Example HTTP response
===== Response 405
[source,json]
----
{
"name" : "Puma",
"type" : 22,
"color" : "Black",
"gender" : "Female",
"breed" : "Mixed"
}
----
[source,xml]
----
<resource><name>Puma</name><type>22</type><color>Black</color><gender>Female</gender><breed>Mixed</breed></resource>
----
<<<
[[_updatepet]]
=== Update an existing pet
....
PUT /pets
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|Pet object that needs to be added to the store|<<_pet,Pet>>
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**400**|Invalid ID supplied|No Content
|**404**|Pet not found|No Content
|**405**|Validation exception|No Content
|===
==== Consumes
* `application/json`
* `application/xml`
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_findpetsbystatus]]
=== Finds Pets by status
....
GET /pets/findByStatus
....
==== Description
Multiple status values can be provided with comma seperated strings
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Query**|**status** +
__optional__|Status values that need to be considered for filter|< string > array(multi)
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|< <<_pet,Pet>> > array
|**400**|Invalid status value|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_findpetsbytags]]
=== Finds Pets by tags
....
GET /pets/findByTags
....
==== Description
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Query**|**tags** +
__optional__|Tags to filter by|< string > array(multi)
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|< <<_pet,Pet>> > array
|**400**|Invalid tag value|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_updatepetwithform]]
=== Updates a pet in the store with form data
....
POST /pets/{petId}
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**petId** +
__required__|ID of pet that needs to be updated|string
|**FormData**|**name** +
__required__|Updated name of the pet|string
|**FormData**|**status** +
__required__|Updated status of the pet|string
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**405**|Invalid input|No Content
|===
==== Consumes
* `application/x-www-form-urlencoded`
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_getpetbyid]]
=== Find pet by ID
....
GET /pets/{petId}
....
==== Description
Returns a pet when ID &lt; 10. ID &gt; 10 or nonintegers will simulate API error conditions
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**petId** +
__required__|ID of the pet|integer(int64)
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|<<_pet,Pet>>
|**400**|Invalid ID supplied|No Content
|**404**|Pet not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**apiKey**|**<<_api_key,api_key>>**|
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_deletepet]]
=== Deletes a pet
....
DELETE /pets/{petId}
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Header**|**api_key** +
__required__||string
|**Path**|**petId** +
__required__|Pet id to delete|integer(int64)
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**400**|Invalid pet value|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* pet
==== Security
[options="header", cols=".^3,.^4,.^13"]
|===
|Type|Name|Scopes
|**oauth2**|**<<_petstore_auth,petstore_auth>>**|write_pets,read_pets
|===
<<<
[[_placeorder]]
=== Place an order for a pet
....
POST /stores/order
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|order placed for purchasing the pet|<<_order,Order>>
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|<<_order,Order>>
|**400**|Invalid Order|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* store
<<<
==== Example HTTP request
===== Request body
[source,json]
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
==== Example HTTP response
===== Response 200
[source,json]
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
<<<
[[_getorderbyid]]
=== Find purchase order by ID
....
GET /stores/order/{orderId}
....
==== Description
For valid response try integer IDs with value &lt;= 5 or &gt; 10. Other values will generated exceptions
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**orderId** +
__required__|ID of pet that needs to be fetched|string
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|<<_order,Order>>
|**400**|Invalid ID supplied|No Content
|**404**|Order not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* store
==== Example HTTP response
===== Response 200
[source,json]
----
{
"id" : 99,
"petId" : 122,
"quantity" : 2,
"shipDate" : "2016-02-22T23:02:05Z",
"status" : "PENDING",
"complete" : true
}
----
<<<
[[_deleteorder]]
=== Delete purchase order by ID
....
DELETE /stores/order/{orderId}
....
==== Description
For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**orderId** +
__required__|ID of the order that needs to be deleted|string
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**400**|Invalid ID supplied|No Content
|**404**|Order not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* store
<<<
[[_createuser]]
=== Create user
....
POST /users
....
==== Description
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|Created user object|<<_user,User>>
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**default**|successful operation|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_createuserswitharrayinput]]
=== Creates list of users with given input array
....
POST /users/createWithArray
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|List of user object|< <<_user,User>> > array
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**default**|successful operation|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_createuserswithlistinput]]
=== Creates list of users with given input array
....
POST /users/createWithList
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Body**|**body** +
__optional__|List of user object|< <<_user,User>> > array
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**default**|successful operation|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_loginuser]]
=== Logs user into the system
....
GET /users/login
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|**Query**|**password** +
__optional__|The password for login in clear text|string|`"testPassword"`
|**Query**|**username** +
__optional__|The user name for login|string|`"testUser"`
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|string
|**400**|Invalid username/password supplied|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_logoutuser]]
=== Logs out current logged in user session
....
GET /users/logout
....
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**default**|successful operation|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_getuserbyname]]
=== Get user by user name
....
GET /users/{username}
....
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|**Path**|**username** +
__required__|The name that needs to be fetched. Use user1 for testing.|string|`"testUser"`
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**200**|successful operation|<<_user,User>>
|**400**|Invalid username supplied|No Content
|**404**|User not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_updateuser]]
=== Updated user
....
PUT /users/{username}
....
==== Description
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**username** +
__required__|name that need to be deleted|string
|**Body**|**body** +
__optional__|Updated user object|<<_user,User>>
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**400**|Invalid user supplied|No Content
|**404**|User not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user
<<<
[[_deleteuser]]
=== Delete user
....
DELETE /users/{username}
....
==== Description
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4"]
|===
|Type|Name|Description|Schema
|**Path**|**username** +
__required__|The name that needs to be deleted|string
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|**400**|Invalid username supplied|No Content
|**404**|User not found|No Content
|===
==== Produces
* `application/json`
* `application/xml`
==== Tags
* user

View File

@@ -0,0 +1,29 @@
[[_securityscheme]]
== Security
[[_petstore_auth]]
=== petstore_auth
[%hardbreaks]
__Type__ : oauth2
__Flow__ : implicit
__Token URL__ : http://petstore.swagger.wordnik.com/api/oauth/dialog
[options="header", cols=".^3,.^17"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===
[[_api_key]]
=== api_key
[%hardbreaks]
__Type__ : apiKey
__Name__ : api_key
__In__ : HEADER