Skip to content

Instantly share code, notes, and snippets.

@nfroidure
Created May 11, 2017 07:25
API Client generation experiment
{
"swagger": "2.0",
"info": {
"description": "WMG web services running altogether",
"version": "5.6.0",
"title": "infrastructure-wmg"
},
"host": "localhost:1664",
"schemes": [
"https"
],
"paths": {
"/{type}/{id}": {
"post": {
"tags": [
"delivery"
],
"deprecated": false,
"summary": "",
"description": "Trigger a new play.",
"operationId": "postPlay",
"consumes": [],
"produces": [
"application/json"
],
"parameters": [
{
"name": "token",
"description": "Deprecated way to set the token",
"type": "string",
"in": "query"
},
{
"name": "access_token",
"description": "Brand new way to set the token in the query string (standard)",
"type": "string",
"in": "query"
},
{
"in": "header",
"name": "Authorization",
"description": "Bearer authorization header",
"type": "string"
},
{
"name": "format",
"type": "string",
"required": false,
"in": "query"
},
{
"name": "type",
"type": "string",
"required": true,
"in": "path"
},
{
"name": "id",
"type": "string",
"required": true,
"in": "path"
}
],
"responses": {
"201": {
"description": "Play processed.",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "When shit hit the fan.",
"schema": {
"type": "object",
"additionalProperties": true,
"required": [
"guruMeditation",
"code"
],
"properties": {
"code": {
"type": "string",
"enum": [
"E_UNEXPECTED"
]
},
"guruMeditation": {
"type": "string"
}
}
}
}
}
},
"get": {
"tags": [
"delivery"
],
"deprecated": true,
"summary": "",
"description": "Trigger a new play (deprecated, use POST).",
"operationId": "getPlay",
"consumes": [],
"produces": [
"application/json"
],
"parameters": [
{
"name": "token",
"description": "Deprecated way to set the token",
"type": "string",
"in": "query"
},
{
"name": "access_token",
"description": "Brand new way to set the token in the query string (standard)",
"type": "string",
"in": "query"
},
{
"in": "header",
"name": "Authorization",
"description": "Bearer authorization header",
"type": "string"
},
{
"name": "format",
"type": "string",
"required": false,
"in": "query"
},
{
"name": "type",
"type": "string",
"required": true,
"in": "path"
},
{
"name": "id",
"type": "string",
"required": true,
"in": "path"
}
],
"responses": {
"201": {
"description": "Play processed.",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "When shit hit the fan.",
"schema": {
"type": "object",
"additionalProperties": true,
"required": [
"guruMeditation",
"code"
],
"properties": {
"code": {
"type": "string",
"enum": [
"E_UNEXPECTED"
]
},
"guruMeditation": {
"type": "string"
}
}
}
}
}
}
}
}
}
'use strict';
__assumeDataProperty(global, "require", __abstract("function", "require"));
__assumeDataProperty(global, "angular", __abstract("function", "angular"));
const querystring = require('querystring');
const angular = require('angular');
const swagger = require('./api.swagger.json');
const HTTP_METHODS = {
options: 'OPTIONS',
head: 'HEAD',
get: 'GET',
post: 'POST',
put: 'PUT',
patch: 'PATCH',
delete: 'DELETE'
};
const sortFn = (a, b) => a > b ? 1 : -1;
const cleanQuery = (query) => {
return Object.keys(query)
.filter((key) => typeof query[key] !== 'undefined')
.filter((key) => (!(query[key] instanceof Array)) || query[key].length !== 0)
.reduce((newQuery, key) => {
newQuery[key] = query[key];
return newQuery;
}, {});
};
const endpoints = Object.keys(swagger.paths)
.reduce((endpoints, path) => {
return Object.keys(swagger.paths[path])
.reduce((endpoints, method) => {
return endpoints.concat(Object.assign({
path,
method,
}, swagger.paths[path][method]));
}, endpoints);
}, []);
angular.module('app').factory('API', apiService);
apiService.$inject = ['ENV', '$http'];
function apiService(ENV, $http) {
return endpoints.reduce(addEndpointProperty, {});
function addEndpointProperty(API, endpoint) {
API[operationId] = (parameters, options = {}) => {
const urlParts = [ENV.apiEndpoint].concat(
path.split('/')
.map((pathPart) => {
const matches = pathPart.match(/{([a-z0-9]+)}/i);
if(matches) {
return parameters[matches[1]];
}
return pathPart;
})
);
const query = endpoint.parameters
.filter(parameter => 'query' === parameter.in)
.reduce((query, parameter) => {
query[parameter.name] = parameters[parameter.name];
return query;
}, {});
const headers = endpoint.parameters
.filter(parameter => 'header' === parameter.in)
.reduce((query, parameter) => {
query[headerCase(parameter.name)] =
parameters[camelCase(parameter.name)];
return query;
}, {});
const bodyDefinition = endpoint.parameters
.find(parameter => 'body' === parameter.in);
// Trick to mock direct file upload since Swagger spec
// has no way to describe it currently
const bodyIsBinary = body.schema &&
'string' === body.schema.type &&
'binary' === body.schema.format;
let data = parameters.body;
let qs = querystring.stringify(cleanQuery(query));
if (data && !bodyIsBinary) {
headers['Content-Type'] = 'application/json';
}
const req = Object.assign(options, {
method: HTTP_METHODS.𐅙variable𐅙method,
url: urlParts.join('') + (qs.length ? '?' + qs : ''),
headers,
data
});
if (bodyIsBinary && data instanceof Blob) {
req.transformRequest = [];
}
return $http(req);
};
return API;
}
}
{
"name": "swagger-api-client",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prepack": "prepack"
},
"author": "",
"license": "MIT",
"dependencies": {
"camel-case": "^3.0.0",
"header-case": "^1.0.1",
"miniquery": "^1.1.2"
},
"devDependencies": {
"prepack": "^0.2.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment