add sinatra template

This commit is contained in:
William Cheng 2015-06-19 02:11:08 +08:00
parent 6ad3a717fe
commit d178d5e7d8
26 changed files with 1269 additions and 409 deletions

View File

@ -26,6 +26,6 @@ fi
# if you've executed sbt assembly previously it will use that instead. # if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/client/petstore/silex" ags="$@ generate -t modules/swagger-codegen/src/main/resources/silex -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l silex -o samples/server/petstore/silex"
java $JAVA_OPTS -jar $executable $ags java $JAVA_OPTS -jar $executable $ags

31
bin/sinatra-petstore-server.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/sinatra -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l sinatra -o samples/server/petstore/sinatra"
java $JAVA_OPTS -jar $executable $ags

View File

@ -0,0 +1,215 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String gemName = null;
protected String moduleName = null;
protected String gemVersion = "1.0.0";
protected String libFolder = "lib";
public SinatraServerCodegen() {
super();
apiPackage = "lib";
outputFolder = "generated-code" + File.separator + "sinatra";
// no model
modelTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".rb");
templateDir = "sinatra";
typeMapping.clear();
languageSpecificPrimitives.clear();
reservedWords = new HashSet<String>(
Arrays.asList(
"__FILE__", "and", "def", "end", "in", "or", "self", "unless", "__LINE__",
"begin", "defined?", "ensure", "module", "redo", "super", "until", "BEGIN",
"break", "do", "false", "next", "rescue", "then", "when", "END", "case",
"else", "for", "nil", "retry", "true", "while", "alias", "class", "elsif",
"if", "not", "return", "undef", "yield")
);
languageSpecificPrimitives.add("int");
languageSpecificPrimitives.add("array");
languageSpecificPrimitives.add("map");
languageSpecificPrimitives.add("string");
languageSpecificPrimitives.add("DateTime");
typeMapping.put("long", "int");
typeMapping.put("integer", "int");
typeMapping.put("Array", "array");
typeMapping.put("String", "string");
typeMapping.put("List", "array");
typeMapping.put("map", "map");
// remove modelPackage and apiPackage added by default
cliOptions.clear();
}
@Override
public void processOpts() {
super.processOpts();
// use constant model/api package (folder path)
//setModelPackage("models");
setApiPackage("api");
supportingFiles.add(new SupportingFile("my_app.mustache", "", "my_app.rb"));
supportingFiles.add(new SupportingFile("Swaggering.rb", libFolder, "Swaggering.rb"));
supportingFiles.add(new SupportingFile("config.ru", "", "config.rb"));
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "sinatra";
}
public String getHelp() {
return "Generates a Sinatra server library.";
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + apiPackage.replace("/", File.separator);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type)) {
return type;
}
} else {
type = swaggerType;
}
if (type == null) {
return null;
}
return type;
}
public String toDefaultValue(Property p) {
return "null";
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, convert to lower case
if (name.matches("^[A-Z_]*$")) {
name = name.toLowerCase();
}
// camelize (lower first character) the variable name
// petId => pet_id
name = underscore(name);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*")) {
name = escapeReservedWord(name);
}
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name)) {
throw new RuntimeException(name + " (reserved word) cannot be used as a model name");
}
// underscore the model file name
// PhoneNumber.rb => phone_number.rb
return underscore(name);
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// e.g. PhoneNumberApi.rb => phone_number_api.rb
return underscore(name) + "_api";
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultApi";
}
// e.g. phone_number_api => PhoneNumberApi
return camelize(name) + "Api";
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (reservedWords.contains(operationId)) {
throw new RuntimeException(operationId + " (reserved word) cannot be used as method name");
}
return underscore(operationId);
}
}

View File

@ -15,6 +15,7 @@ io.swagger.codegen.languages.RubyClientCodegen
io.swagger.codegen.languages.ScalaClientCodegen io.swagger.codegen.languages.ScalaClientCodegen
io.swagger.codegen.languages.ScalatraServerCodegen io.swagger.codegen.languages.ScalatraServerCodegen
io.swagger.codegen.languages.SilexServerCodegen io.swagger.codegen.languages.SilexServerCodegen
io.swagger.codegen.languages.SinatraServerCodegen
io.swagger.codegen.languages.SpringMVCServerCodegen io.swagger.codegen.languages.SpringMVCServerCodegen
io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticDocCodegen
io.swagger.codegen.languages.StaticHtmlGenerator io.swagger.codegen.languages.StaticHtmlGenerator

View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem "sinatra"
gem "sinatra-cross_origin"

View File

@ -0,0 +1,29 @@
# Swagger for Sinatra
## Overview
This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find
out more about both the spec and the framework at http://swagger.wordnik.com. For more information about
Wordnik's APIs, please visit http://developer.wordnik.com.
## Prerequisites
You need to install ruby 1.9.3 and the following gems:
```
sinatra
sinatra-cross_origin
```
## Getting started
This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project.
```
rackup -p 4567 config.ru
```
In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL:
```
http://localhost:4567/resources.json
```
Voila!

View File

@ -0,0 +1,154 @@
require 'json'
require 'sinatra/base'
require 'sinatra/cross_origin'
class Configuration
attr_accessor :base_path, :api_version, :swagger_version, :format_specifier
def initialize
@api_version = '1.0'
@base_path = 'http://localhost:4567'
@swagger_version = '1.1'
@format_specifier = ".json"
end
end
class Swaggering < Sinatra::Base
register Sinatra::CrossOrigin
@@routes = {}
@@configuration = Configuration.new
attr_accessor :configuration
def self.configure
get("/resources" + @@configuration.format_specifier) {
cross_origin
Swaggering.to_resource_listing
}
@@configuration ||= Configuration.new
yield(@@configuration) if block_given?
end
def self.add_route(method, path, swag={}, opts={}, &block)
fullPath = swag["resourcePath"].to_s + @@configuration.format_specifier + path
accepted = case method
when 'get'
get(fullPath, opts, &block)
true
when 'post'
post(fullPath, opts, &block)
true
when 'delete'
delete(fullPath, opts, &block)
true
when 'put'
put(fullPath, opts, &block)
true
else
false
end
if accepted then
resourcePath = swag["resourcePath"].to_s
ops = @@routes[resourcePath]
if ops.nil?
ops = Array.new
@@routes.merge!(resourcePath => ops)
get(resourcePath + @@configuration.format_specifier) do
cross_origin
Swaggering.to_api(resourcePath)
end
end
swag.merge!("httpMethod" => method.to_s.upcase)
ops.push(swag)
end
end
def self.to_resource_listing
apis = Array.new
(@@routes.keys).each do |key|
api = {
"path" => (key + ".{format}"),
"description" => "no description"
}
apis.push api
end
resource = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"apis" => apis
}
resource.to_json
end
def self.to_api(resourcePath)
apis = {}
models = []
@@routes[resourcePath].each do |route|
endpoint = route["endpoint"].gsub(/:(\w+)(\/?)/,'{\1}\2')
path = (resourcePath + ".{format}" + endpoint)
api = apis[path]
if api.nil?
api = {"path" => path, "description" => "description", "operations" => []}
apis.merge!(path => api)
end
parameters = route["parameters"]
unless parameters.nil? then
parameters.each do |param|
av_string = param["allowableValues"]
unless av_string.nil?
if av_string.count('[') > 0
pattern = /^([A-Z]*)\[(.*)\]/
match = pattern.match av_string
case match.to_a[1]
when "LIST"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "LIST",
"values" => allowables
}
when "RANGE"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "RANGE",
"min" => allowables[0],
"max" => allowables[1]
}
end
end
end
end
end
op = {
"httpMethod" => route["httpMethod"],
"description" => route["summary"],
"responseClass" => route["responseClass"],
"notes" => route["notes"],
"nickname" => route["nickname"],
"summary" => route["summary"],
"parameters" => route["parameters"]
}
api["operations"].push(op)
end
api_listing = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"basePath" => @@configuration.base_path,
"resourcePath" => resourcePath,
"apis" => apis.values,
"models" => models
}
api_listing.to_json
end
end

View File

@ -0,0 +1,57 @@
require 'json'
{{#operations}}
{{#operation}}
MyApp.add_route('{{httpMethod}}', '{{path}}', {
"resourcePath" => "/{{baseName}}",
"summary" => "{{{summary}}}",
"nickname" => "{{nickname}}",
"responseClass" => "{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}",
"endpoint" => "{{path}}",
"notes" => "{{{notes}}}",
"parameters" => [
{{#queryParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "query",
"allowMultiple" => {{allowMultiple}},
"allowableValues" => "{{allowableValues}}",
{{#defaultValue}}"defaultValue" => {{{defaultValue}}}{{/defaultValue}}
},
{{/queryParams}}
{{#pathParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "path",
},
{{/pathParams}}
{{#headerParams}}
{
"name" => "{{paramName}}",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "header",
},
{{/headerParams}}
{{#bodyParams}}
{
"name" => "body",
"description" => "{{description}}",
"dataType" => "{{swaggerDataType}}",
"paramType" => "body",
}
{{/bodyParams}}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,2 @@
require './my_app'
run MyApp

View File

@ -0,0 +1,12 @@
require './lib/swaggering'
# only need to extend if you want special configuration!
class MyApp < Swaggering
self.configure do |config|
config.api_version = '0.2'
end
end
{{#apis}}
require './lib/{{className}}.rb'
{{/apis}}

View File

@ -1,5 +0,0 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>

View File

@ -1,10 +0,0 @@
# Swagger generated server
## Overview
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a PHP server.
This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here:
[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/)

View File

@ -1,5 +0,0 @@
{
"require": {
"silex/silex": "~1.2"
}
}

View File

@ -1,184 +0,0 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Silex\Application;
$app = new Silex\Application();
$app->POST('/user', function(Application $app, Request $request) {
return new Response('How about implementing createUser as a POST method ?');
});
$app->POST('/user/createWithArray', function(Application $app, Request $request) {
return new Response('How about implementing createUsersWithArrayInput as a POST method ?');
});
$app->POST('/user/createWithList', function(Application $app, Request $request) {
return new Response('How about implementing createUsersWithListInput as a POST method ?');
});
$app->GET('/user/login', function(Application $app, Request $request) {
$username = $request->get('username'); $password = $request->get('password');
return new Response('How about implementing loginUser as a GET method ?');
});
$app->GET('/user/logout', function(Application $app, Request $request) {
return new Response('How about implementing logoutUser as a GET method ?');
});
$app->GET('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing getUserByName as a GET method ?');
});
$app->PUT('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing updateUser as a PUT method ?');
});
$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing deleteUser as a DELETE method ?');
});
$app->PUT('/pet', function(Application $app, Request $request) {
return new Response('How about implementing updatePet as a PUT method ?');
});
$app->POST('/pet', function(Application $app, Request $request) {
return new Response('How about implementing addPet as a POST method ?');
});
$app->GET('/pet/findByStatus', function(Application $app, Request $request) {
$status = $request->get('status');
return new Response('How about implementing findPetsByStatus as a GET method ?');
});
$app->GET('/pet/findByTags', function(Application $app, Request $request) {
$tags = $request->get('tags');
return new Response('How about implementing findPetsByTags as a GET method ?');
});
$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
return new Response('How about implementing getPetById as a GET method ?');
});
$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
$name = $request->get('name'); $status = $request->get('status');
return new Response('How about implementing updatePetWithForm as a POST method ?');
});
$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
return new Response('How about implementing deletePet as a DELETE method ?');
});
$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) {
$additional_metadata = $request->get('additional_metadata'); $file = $request->get('file');
return new Response('How about implementing uploadFile as a POST method ?');
});
$app->GET('/store/inventory', function(Application $app, Request $request) {
return new Response('How about implementing getInventory as a GET method ?');
});
$app->POST('/store/order', function(Application $app, Request $request) {
return new Response('How about implementing placeOrder as a POST method ?');
});
$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) {
return new Response('How about implementing getOrderById as a GET method ?');
});
$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) {
return new Response('How about implementing deleteOrder as a DELETE method ?');
});
$app->run();

View File

@ -1,5 +0,0 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>

View File

@ -1,10 +0,0 @@
# Swagger generated server
## Overview
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
[swagger-spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a PHP server.
This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here:
[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/silex/)

View File

@ -1,5 +0,0 @@
{
"require": {
"silex/silex": "~1.2"
}
}

View File

@ -1,184 +0,0 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Silex\Application;
$app = new Silex\Application();
$app->POST('/user', function(Application $app, Request $request) {
return new Response('How about implementing createUser as a POST method ?');
});
$app->POST('/user/createWithArray', function(Application $app, Request $request) {
return new Response('How about implementing createUsersWithArrayInput as a POST method ?');
});
$app->POST('/user/createWithList', function(Application $app, Request $request) {
return new Response('How about implementing createUsersWithListInput as a POST method ?');
});
$app->GET('/user/login', function(Application $app, Request $request) {
$username = $request->get('username'); $password = $request->get('password');
return new Response('How about implementing loginUser as a GET method ?');
});
$app->GET('/user/logout', function(Application $app, Request $request) {
return new Response('How about implementing logoutUser as a GET method ?');
});
$app->GET('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing getUserByName as a GET method ?');
});
$app->PUT('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing updateUser as a PUT method ?');
});
$app->DELETE('/user/{username}', function(Application $app, Request $request, $username) {
return new Response('How about implementing deleteUser as a DELETE method ?');
});
$app->PUT('/pet', function(Application $app, Request $request) {
return new Response('How about implementing updatePet as a PUT method ?');
});
$app->POST('/pet', function(Application $app, Request $request) {
return new Response('How about implementing addPet as a POST method ?');
});
$app->GET('/pet/findByStatus', function(Application $app, Request $request) {
$status = $request->get('status');
return new Response('How about implementing findPetsByStatus as a GET method ?');
});
$app->GET('/pet/findByTags', function(Application $app, Request $request) {
$tags = $request->get('tags');
return new Response('How about implementing findPetsByTags as a GET method ?');
});
$app->GET('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
return new Response('How about implementing getPetById as a GET method ?');
});
$app->POST('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
$name = $request->get('name'); $status = $request->get('status');
return new Response('How about implementing updatePetWithForm as a POST method ?');
});
$app->DELETE('/pet/{petId}', function(Application $app, Request $request, $pet_id) {
return new Response('How about implementing deletePet as a DELETE method ?');
});
$app->POST('/pet/{petId}/uploadImage', function(Application $app, Request $request, $pet_id) {
$additional_metadata = $request->get('additional_metadata'); $file = $request->get('file');
return new Response('How about implementing uploadFile as a POST method ?');
});
$app->GET('/store/inventory', function(Application $app, Request $request) {
return new Response('How about implementing getInventory as a GET method ?');
});
$app->POST('/store/order', function(Application $app, Request $request) {
return new Response('How about implementing placeOrder as a POST method ?');
});
$app->GET('/store/order/{orderId}', function(Application $app, Request $request, $order_id) {
return new Response('How about implementing getOrderById as a GET method ?');
});
$app->DELETE('/store/order/{orderId}', function(Application $app, Request $request, $order_id) {
return new Response('How about implementing deleteOrder as a DELETE method ?');
});
$app->run();

View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem "sinatra"
gem "sinatra-cross_origin"

View File

@ -0,0 +1,29 @@
# Swagger for Sinatra
## Overview
This is a project to provide Swagger support inside the [Sinatra](http://www.sinatrarb.com/) framework. You can find
out more about both the spec and the framework at http://swagger.wordnik.com. For more information about
Wordnik's APIs, please visit http://developer.wordnik.com.
## Prerequisites
You need to install ruby 1.9.3 and the following gems:
```
sinatra
sinatra-cross_origin
```
## Getting started
This sample was generated with the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project.
```
rackup -p 4567 config.ru
```
In your [swagger ui](https://github.com/wordnik/swagger-ui), put in the following URL:
```
http://localhost:4567/resources.json
```
Voila!

View File

@ -0,0 +1,231 @@
require 'json'
MyApp.add_route('PUT', '/pet', {
"resourcePath" => "/Pet",
"summary" => "Update an existing pet",
"nickname" => "update_pet",
"responseClass" => "void",
"endpoint" => "/pet",
"notes" => "",
"parameters" => [
{
"name" => "body",
"description" => "Pet object that needs to be added to the store",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/pet', {
"resourcePath" => "/Pet",
"summary" => "Add a new pet to the store",
"nickname" => "add_pet",
"responseClass" => "void",
"endpoint" => "/pet",
"notes" => "",
"parameters" => [
{
"name" => "body",
"description" => "Pet object that needs to be added to the store",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/pet/findByStatus', {
"resourcePath" => "/Pet",
"summary" => "Finds Pets by status",
"nickname" => "find_pets_by_status",
"responseClass" => "array[Pet]",
"endpoint" => "/pet/findByStatus",
"notes" => "Multiple status values can be provided with comma seperated strings",
"parameters" => [
{
"name" => "status",
"description" => "Status values that need to be considered for filter",
"dataType" => "",
"paramType" => "query",
"allowMultiple" => ,
"allowableValues" => "",
"defaultValue" => available
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/pet/findByTags', {
"resourcePath" => "/Pet",
"summary" => "Finds Pets by tags",
"nickname" => "find_pets_by_tags",
"responseClass" => "array[Pet]",
"endpoint" => "/pet/findByTags",
"notes" => "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"parameters" => [
{
"name" => "tags",
"description" => "Tags to filter by",
"dataType" => "",
"paramType" => "query",
"allowMultiple" => ,
"allowableValues" => "",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/pet/{petId}', {
"resourcePath" => "/Pet",
"summary" => "Find pet by ID",
"nickname" => "get_pet_by_id",
"responseClass" => "Pet",
"endpoint" => "/pet/{petId}",
"notes" => "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
"parameters" => [
{
"name" => "pet_id",
"description" => "ID of pet that needs to be fetched",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/pet/{petId}', {
"resourcePath" => "/Pet",
"summary" => "Updates a pet in the store with form data",
"nickname" => "update_pet_with_form",
"responseClass" => "void",
"endpoint" => "/pet/{petId}",
"notes" => "",
"parameters" => [
{
"name" => "pet_id",
"description" => "ID of pet that needs to be updated",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('DELETE', '/pet/{petId}', {
"resourcePath" => "/Pet",
"summary" => "Deletes a pet",
"nickname" => "delete_pet",
"responseClass" => "void",
"endpoint" => "/pet/{petId}",
"notes" => "",
"parameters" => [
{
"name" => "pet_id",
"description" => "Pet id to delete",
"dataType" => "",
"paramType" => "path",
},
{
"name" => "api_key",
"description" => "",
"dataType" => "",
"paramType" => "header",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/pet/{petId}/uploadImage', {
"resourcePath" => "/Pet",
"summary" => "uploads an image",
"nickname" => "upload_file",
"responseClass" => "void",
"endpoint" => "/pet/{petId}/uploadImage",
"notes" => "",
"parameters" => [
{
"name" => "pet_id",
"description" => "ID of pet to update",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end

View File

@ -0,0 +1,103 @@
require 'json'
MyApp.add_route('GET', '/store/inventory', {
"resourcePath" => "/Store",
"summary" => "Returns pet inventories by status",
"nickname" => "get_inventory",
"responseClass" => "map[string,int]",
"endpoint" => "/store/inventory",
"notes" => "Returns a map of status codes to quantities",
"parameters" => [
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/store/order', {
"resourcePath" => "/Store",
"summary" => "Place an order for a pet",
"nickname" => "place_order",
"responseClass" => "Order",
"endpoint" => "/store/order",
"notes" => "",
"parameters" => [
{
"name" => "body",
"description" => "order placed for purchasing the pet",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/store/order/{orderId}', {
"resourcePath" => "/Store",
"summary" => "Find purchase order by ID",
"nickname" => "get_order_by_id",
"responseClass" => "Order",
"endpoint" => "/store/order/{orderId}",
"notes" => "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
"parameters" => [
{
"name" => "order_id",
"description" => "ID of pet that needs to be fetched",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('DELETE', '/store/order/{orderId}', {
"resourcePath" => "/Store",
"summary" => "Delete purchase order by ID",
"nickname" => "delete_order",
"responseClass" => "void",
"endpoint" => "/store/order/{orderId}",
"notes" => "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"parameters" => [
{
"name" => "order_id",
"description" => "ID of the order that needs to be deleted",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end

View File

@ -0,0 +1,231 @@
require 'json'
MyApp.add_route('POST', '/user', {
"resourcePath" => "/User",
"summary" => "Create user",
"nickname" => "create_user",
"responseClass" => "void",
"endpoint" => "/user",
"notes" => "This can only be done by the logged in user.",
"parameters" => [
{
"name" => "body",
"description" => "Created user object",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/user/createWithArray', {
"resourcePath" => "/User",
"summary" => "Creates list of users with given input array",
"nickname" => "create_users_with_array_input",
"responseClass" => "void",
"endpoint" => "/user/createWithArray",
"notes" => "",
"parameters" => [
{
"name" => "body",
"description" => "List of user object",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('POST', '/user/createWithList', {
"resourcePath" => "/User",
"summary" => "Creates list of users with given input array",
"nickname" => "create_users_with_list_input",
"responseClass" => "void",
"endpoint" => "/user/createWithList",
"notes" => "",
"parameters" => [
{
"name" => "body",
"description" => "List of user object",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/user/login', {
"resourcePath" => "/User",
"summary" => "Logs user into the system",
"nickname" => "login_user",
"responseClass" => "string",
"endpoint" => "/user/login",
"notes" => "",
"parameters" => [
{
"name" => "username",
"description" => "The user name for login",
"dataType" => "",
"paramType" => "query",
"allowMultiple" => ,
"allowableValues" => "",
},
{
"name" => "password",
"description" => "The password for login in clear text",
"dataType" => "",
"paramType" => "query",
"allowMultiple" => ,
"allowableValues" => "",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/user/logout', {
"resourcePath" => "/User",
"summary" => "Logs out current logged in user session",
"nickname" => "logout_user",
"responseClass" => "void",
"endpoint" => "/user/logout",
"notes" => "",
"parameters" => [
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('GET', '/user/{username}', {
"resourcePath" => "/User",
"summary" => "Get user by user name",
"nickname" => "get_user_by_name",
"responseClass" => "User",
"endpoint" => "/user/{username}",
"notes" => "",
"parameters" => [
{
"name" => "username",
"description" => "The name that needs to be fetched. Use user1 for testing. ",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('PUT', '/user/{username}', {
"resourcePath" => "/User",
"summary" => "Updated user",
"nickname" => "update_user",
"responseClass" => "void",
"endpoint" => "/user/{username}",
"notes" => "This can only be done by the logged in user.",
"parameters" => [
{
"name" => "username",
"description" => "name that need to be deleted",
"dataType" => "",
"paramType" => "path",
},
{
"name" => "body",
"description" => "Updated user object",
"dataType" => "",
"paramType" => "body",
}
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end
MyApp.add_route('DELETE', '/user/{username}', {
"resourcePath" => "/User",
"summary" => "Delete user",
"nickname" => "delete_user",
"responseClass" => "void",
"endpoint" => "/user/{username}",
"notes" => "This can only be done by the logged in user.",
"parameters" => [
{
"name" => "username",
"description" => "The name that needs to be deleted",
"dataType" => "",
"paramType" => "path",
},
]}) do
cross_origin
# the guts live here
{"message" => "yes, it worked"}.to_json
end

View File

@ -0,0 +1,2 @@
require './my_app'
run MyApp

View File

@ -0,0 +1,154 @@
require 'json'
require 'sinatra/base'
require 'sinatra/cross_origin'
class Configuration
attr_accessor :base_path, :api_version, :swagger_version, :format_specifier
def initialize
@api_version = '1.0'
@base_path = 'http://localhost:4567'
@swagger_version = '1.1'
@format_specifier = ".json"
end
end
class Swaggering < Sinatra::Base
register Sinatra::CrossOrigin
@@routes = {}
@@configuration = Configuration.new
attr_accessor :configuration
def self.configure
get("/resources" + @@configuration.format_specifier) {
cross_origin
Swaggering.to_resource_listing
}
@@configuration ||= Configuration.new
yield(@@configuration) if block_given?
end
def self.add_route(method, path, swag={}, opts={}, &block)
fullPath = swag["resourcePath"].to_s + @@configuration.format_specifier + path
accepted = case method
when 'get'
get(fullPath, opts, &block)
true
when 'post'
post(fullPath, opts, &block)
true
when 'delete'
delete(fullPath, opts, &block)
true
when 'put'
put(fullPath, opts, &block)
true
else
false
end
if accepted then
resourcePath = swag["resourcePath"].to_s
ops = @@routes[resourcePath]
if ops.nil?
ops = Array.new
@@routes.merge!(resourcePath => ops)
get(resourcePath + @@configuration.format_specifier) do
cross_origin
Swaggering.to_api(resourcePath)
end
end
swag.merge!("httpMethod" => method.to_s.upcase)
ops.push(swag)
end
end
def self.to_resource_listing
apis = Array.new
(@@routes.keys).each do |key|
api = {
"path" => (key + ".{format}"),
"description" => "no description"
}
apis.push api
end
resource = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"apis" => apis
}
resource.to_json
end
def self.to_api(resourcePath)
apis = {}
models = []
@@routes[resourcePath].each do |route|
endpoint = route["endpoint"].gsub(/:(\w+)(\/?)/,'{\1}\2')
path = (resourcePath + ".{format}" + endpoint)
api = apis[path]
if api.nil?
api = {"path" => path, "description" => "description", "operations" => []}
apis.merge!(path => api)
end
parameters = route["parameters"]
unless parameters.nil? then
parameters.each do |param|
av_string = param["allowableValues"]
unless av_string.nil?
if av_string.count('[') > 0
pattern = /^([A-Z]*)\[(.*)\]/
match = pattern.match av_string
case match.to_a[1]
when "LIST"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "LIST",
"values" => allowables
}
when "RANGE"
allowables = match.to_a[2].split(',')
param["allowableValues"] = {
"valueType" => "RANGE",
"min" => allowables[0],
"max" => allowables[1]
}
end
end
end
end
end
op = {
"httpMethod" => route["httpMethod"],
"description" => route["summary"],
"responseClass" => route["responseClass"],
"notes" => route["notes"],
"nickname" => route["nickname"],
"summary" => route["summary"],
"parameters" => route["parameters"]
}
api["operations"].push(op)
end
api_listing = {
"apiVersion" => @@configuration.api_version,
"swaggerVersion" => @@configuration.swagger_version,
"basePath" => @@configuration.base_path,
"resourcePath" => resourcePath,
"apis" => apis.values,
"models" => models
}
api_listing.to_json
end
end

View File

@ -0,0 +1,9 @@
require './lib/swaggering'
# only need to extend if you want special configuration!
class MyApp < Swaggering
self.configure do |config|
config.api_version = '0.2'
end
end