FSN#40005 Documenteren API2 volgens OpenAPI Specification savepoint

Enkele 'lastige' modellen nog uitgeschakeld in dispatch met nodoc: true

svn path=/Website/trunk/; revision=33285
This commit is contained in:
Jos Groot Lipman
2017-03-28 10:42:10 +00:00
parent 12448eeb30
commit 02837cba5c
5 changed files with 381 additions and 18 deletions

View File

@@ -13,7 +13,9 @@
var api2_mapper = {
// De 'name' moet hier gelijk zijn aan model.records_name
"realestateproperties" : { "filename": "appl/mgt/alg_kenmerk.asp" },
"swagger" : { "filename": "appl/api2/api_swagger.asp" },
"realestateproperties" : { "filename": "appl/mgt/alg_kenmerk.asp", "nodoc": true },
"buildingfunctions" : { "filename": "appl/mgt/alg_srtgebouw.asp" },
"terrainfunctions" : { "filename": "appl/mgt/alg_srtterreinsector.asp" },
"regions" : { "filename": "appl/api2/api_regions.asp", "module": "ALG" },
@@ -40,8 +42,8 @@ var api2_mapper = {
"budgetcostcategories" : { "filename": "appl/mgt/bgt_kostenrubriek.asp" },
"budgetprojects" : { "filename": "appl/mgt/bgt_project.asp" },
"graphiclabels" : { "filename": "appl/mgt/cad_label.asp" },
"graphiclegendas" : { "filename": "appl/mgt/cad_legenda.asp" },
"graphiclegendavalues" : { "filename": "appl/mgt/cad_legendawaarde.asp" },
"graphiclegends" : { "filename": "appl/mgt/cad_legenda.asp" },
"graphiclegendvalues" : { "filename": "appl/mgt/cad_legendawaarde.asp" },
"graphicthemes" : { "filename": "appl/mgt/cad_thema.asp" },
"contractdisciplines" : { "filename": "appl/mgt/cnt_discipline.asp" },
"contractproperties" : { "filename": "appl/mgt/cnt_kenmerk.asp" },
@@ -53,20 +55,20 @@ var api2_mapper = {
"exportfunctions" : { "filename": "appl/mgt/fac_export_app.asp" },
"authorizationfunctions" : { "filename": "appl/mgt/fac_functie.asp" },
"authorizationgroups" : { "filename": "appl/mgt/fac_groep.asp" },
"authorizations" : { "filename": "appl/mgt/fac_groeprechten.asp" },
"authorizations" : { "filename": "appl/mgt/fac_groeprechten.asp", "nodoc": true },
"identityproviders" : { "filename": "appl/mgt/fac_idp.asp" },
"importfunctions" : { "filename": "appl/mgt/fac_import_app.asp" },
"notificationjobs" : { "filename": "appl/mgt/fac_notificatie_job.asp" },
"profiles" : { "filename": "appl/mgt/fac_profiel.asp" },
"profilevalues" : { "filename": "appl/mgt/fac_profielwaarde.asp" },
"notificationtypes" : { "filename": "appl/mgt/fac_srtnotificatie.asp" },
"customgraphs" : { "filename": "appl/mgt/fac_usrgraph.asp" },
"customgraphs" : { "filename": "appl/mgt/fac_usrgraph.asp", "nodoc": true },
"customtables" : { "filename": "appl/mgt/fac_usrtab.asp" },
"widgets" : { "filename": "appl/mgt/fac_widget.asp" },
"knowledgeproperties" : { "filename": "appl/mgt/faq_kenmerk.asp" },
"vattables" : { "filename": "appl/mgt/fin_btwtabel.asp" },
"invoiceproperties" : { "filename": "appl/mgt/fin_kenmerk.asp" },
"saleinvoicelines" : { "filename": "appl/mgt/fin_verkoopfactuur.asp" },
"saleinvoicelines" : { "filename": "appl/mgt/fin_verkoopfactuur.asp", "nodoc": true },
"taskhandlings" : { "filename": "appl/mgt/ins_controlemode.asp" },
"objectdisciplines" : { "filename": "appl/mgt/ins_discipline.asp" },
"objectproperties" : { "filename": "appl/mgt/ins_kenmerk.asp" },
@@ -88,7 +90,7 @@ var api2_mapper = {
"issueordertypes" : { "filename": "appl/mgt/mld_typeopdr.asp" },
"daysoff" : { "filename": "appl/mgt/mld_vrije_dagen.asp" },
"workflows" : { "filename": "appl/mgt/mld_workflow.asp" },
"workflowsteps" : { "filename": "appl/mgt/mld_workflowstep.asp" },
"workflowsteps" : { "filename": "appl/mgt/mld_workflowstep.asp", "nodoc": true },
"workflowexpressions" : { "filename": "appl/mgt/mld_workflow_expression.asp" },
"issuedisciplines" : { "filename": "appl/api2/api_issuedisciplines.asp", "module": "MLD" },
"orders" : { "filename": "appl/api2/api_orders.asp", "module": "MLD" },
@@ -96,11 +98,11 @@ var api2_mapper = {
"issuetypes" : { "filename": "appl/api2/api_issuetypes.asp", "module": "MLD" },
"pinboardcategories" : { "filename": "appl/mgt/mrk_discipline.asp" },
"services" : { "filename": "appl/mgt/prs_dienst.asp" },
"basisproperties" : { "filename": "appl/mgt/prs_kenmerk.asp" },
"basisproperties" : { "filename": "appl/mgt/prs_kenmerk.asp", "nodoc": true },
"combinationvalidation" : { "filename": "appl/mgt/prs_kostencombinatie.asp" },
"costtypes" : { "filename": "appl/mgt/prs_kostensoort.asp" },
"costtypegroups" : { "filename": "appl/mgt/prs_kostensoortgrp.asp" },
"persons" : { "filename": "appl/mgt/prs_perslid.asp" },
"persons" : { "filename": "appl/mgt/prs_perslid.asp", "nodoc": true },
"relationtypes" : { "filename": "appl/mgt/prs_relatietype.asp" },
"employeefunctions" : { "filename": "appl/mgt/prs_srtperslid.asp" },
"basispacelists" : { "filename": "appl/mgt/prs_staffel.asp" },
@@ -124,20 +126,19 @@ var api2_mapper = {
"reservablecatalog" : { "filename": "appl/api2/api_reservablecatalog.asp", "module": "RES" },
"res_ruimtes" : { "filename": "appl/api2/api_res_ruimtes.asp", "module": "RES" },
"attachments" : { "filename": "appl/api2/api_attachments.asp", "module": "API" },
"attachments" : { "filename": "appl/api2/api_attachments.asp", "module": "API", "nodoc": true },
"doc" : { "filename": "appl/api2/api_doc.asp", "module": "API" },
"apis" : { "filename": "appl/api2/api_apis.asp", "module": "API" },
"about" : { "filename": "appl/api2/api_about.asp", "module": "API" },
"cadcontours" : { "filename": "appl/api2/api_cadcontours.asp", "module": "CAD" },
"contracts" : { "filename": "appl/api2/api_contracts.asp", "module": "CNT" },
"notes" : { "filename": "appl/api2/api_notes.asp", "module": "FAC" },
"notes" : { "filename": "appl/api2/api_notes.asp", "module": "FAC", "nodoc": true },
"approvals" : { "filename": "appl/api2/api_approvals.asp", "module": "FAC" },
"settings" : { "filename": "appl/api2/api_settings.asp", "module": "FAC" },
"reportsx" : { "filename": "appl/api2/api_reportsx.asp", "module": "FAC" },
"reports" : { "filename": "appl/api2/api_reports.asp", "module": "FAC" },
"reports" : { "filename": "appl/api2/api_reports.asp", "module": "FAC", "nodoc": true },
"invoices" : { "filename": "appl/api2/api_invoices.asp", "module": "FIN" },
"objects" : { "filename": "appl/api2/api_objects.asp", "module": "INS" },
"persons" : { "filename": "appl/api2/api_persons.asp", "module": "PRS" },
"companies" : { "filename": "appl/api2/api_companies.asp", "module": "PRS" },
"generictables" : { "filename": "appl/mgt/mgt_generic.asp", "hidden": true },

View File

@@ -137,6 +137,81 @@ api2_rest = {
Response.End;
}
},
swaggerschema: function _swaggerschema(model)
{
var schema = {
"type":"object",
"properties":{},
"required": [],
"xml":{
"name": model.record_name
}
}
for (var fld in model.fields)
{
if (fld.substring(0,1) == "_")
continue;
var field = model.fields[fld];
if (field.hidden)
continue;
if (field.required)
schema.required.push(fld);
switch (field.typ)
{
case "key":
var prop = {
"type":"integer",
"format":"int64"
};
break;
case "float":
case "currency":
var prop = {
"type":"float",
"format":"float"
};
break;
case "number":
var prop = {
"type":"integer",
"format":"int64"
};
break;
case "check":
case "check0":
var prop = {
"type":"integer",
"format":"int64"
};
break;
case "varchar":
case "memo":
var prop = {
"type":"string",
"format":"string"
};
break;
case "date":
var prop = {
"type":"dateTime",
"format":"date-time"
};
break;
case "datetime":
var prop = {
"type":"dateTime",
"format":"date-time"
};
break;
break;
default:
continue;
}
prop.description = field.label;
schema["properties"][fld] = prop;
}
return schema;
},
process: function _process(model)
{
var wasCodePage = Session.Codepage;
@@ -223,7 +298,7 @@ api2_rest = {
model.autfunctionname = L("lcl_" + model.autfunction);
// TODO: velden strippen waar je niets mee te maken hebt?
}
else if (format == "api")
else if (format == "api" && getQParamInt("swagger", 0) == 0)
{
// TODO: Onderstaande in een of ander standaardformaat opleveren?
var result = { id: model.records_name,
@@ -257,6 +332,158 @@ api2_rest = {
});
}
}
else if (format == "api" && getQParamInt("swagger", 0) == 1)
{
// Swagger
var result = {
"get": {
"tags":[
getQParamSafe("module", "XXX")
],
"summary": "Get all {0}".format(model.records_title),
"description": "Returns all {0} from the system that the user has access to".format(model.records_title),
"responses": {
"200": {
"description": "A list of " + model.records_title
}
},
"security":[
{
"api_key":[
]
}
]
}
};
if (getQParamInt("single", 0) == 1)
{
result["get"].summary = "Get one {0}".format(model.record_title);
result["get"].parameters = [
{
"name":"id",
"in":"path",
"description":"ID of {0} to return".format(model.record_title),
"required":true,
"type":"integer",
"format":"int64"
}
];
}
if (getQParamInt("single", 0) == 1 && model["REST_POST"])
{
result["post"] = {
"tags":[
getQParamSafe("module", "XXX")
],
"summary":"Add a new {0} to FACILITOR".format(model.record_title),
"description":"",
"operationId":"add" + model.records_name,
"parameters":[
{
"in":"body",
"name":"body",
"description":"{0} object that needs to be added".format(model.record_title),
"required":true,
"xxxschema":{
"$ref":"#/definitions/Pet"
},
"schema": api2_rest.swaggerschema(model)
}
],
"responses":{
"405":{
"description":"Invalid input"
}
},
"security":[
{
"petstore_auth":[
"write:pets",
"read:pets"
]
}
]
}
}
if (getQParamInt("single", 0) == 1 && model["REST_PUT"])
{
result["put"] = {
"tags":[
getQParamSafe("module", "XXX")
],
"summary":"Update an existing {0} in FACILITOR".format(model.record_title),
"description":"",
"operationId":"add" + model.records_name,
"parameters":[
{
"name":"id",
"in":"path",
"description":"ID of {0} to update".format(model.record_title),
"required":true,
"type":"integer",
"format":"int64"
},
{
"in":"body",
"name":"body",
"description":"{0} object that needs to be updated".format(model.record_title),
"required":true,
"xxxschema":{
"$ref":"#/definitions/Pet"
},
"schema": api2_rest.swaggerschema(model)
}
],
"responses":{
"405":{
"description":"Invalid input"
}
},
"security":[
{
"petstore_auth":[
"write:pets",
"read:pets"
]
}
]
}
}
if (getQParamInt("single", 0) == 1 && model["REST_DELETE"])
{
result["delete"] = {
"tags":[
getQParamSafe("module", "XXX")
],
"summary":"Delete a {0} from FACILITOR".format(model.record_title),
"description":"",
"operationId":"add" + model.records_name,
"parameters":[
{
"name":"id",
"in":"path",
"description":"ID of {0} to delete".format(model.record_title),
"required":true,
"type":"integer",
"format":"int64"
}
],
"responses":{
"405":{
"description":"Invalid input"
}
},
"security":[
{
"petstore_auth":[
"write:pets",
"read:pets"
]
}
]
}
}
}
else
{
if (method == "DELETE")
@@ -388,7 +615,9 @@ api2_rest = {
if (format == "html" || format == "json" || format == "table")
{
var result = { };
if (single)
if (model.formatted_get)
result = data;
else if (single)
result[model.record_name] = data[0];
else
{
@@ -572,8 +801,8 @@ api2_rest = {
{
var tds = [];
for (var fld in data[0])
tds.push(fld);
trs.push("<th>" + tds.join("</th><th>") + "</th>");
tds.push("<th title='{0}'>{1}</th>".format(safe.htmlattr(model.fields[fld].label), fld));
trs.push(tds.join(""));
}
for (var i = 0; i < data.length; i++)
{

25
APPL/API2/api_swagger.asp Normal file
View File

@@ -0,0 +1,25 @@
<%@ language = "JavaScript" %>
<% /*
$Revision$
$Id$
File: api_swagger.asp
Description: META API
Parameters:
Context:
Notes:
*/
DOCTYPE_Disable = true;
ANONYMOUS_Allowed = 1; // Eigenlijk niet waar. We regelen echter alles zelf
THIS_FILE = "appl/api/api_swagger.asp";
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="./api2_rest.inc" -->
<!-- #include file="../Shared/json2.js" -->
<!-- #include file="./model_swagger.inc" -->
<%
api2_rest.process(model_apis);
%>

View File

@@ -47,7 +47,7 @@ function model_cad_thema()
"typ": "varchar",
"filter": "like"
},
"graphiclegenda": {
"graphiclegend": {
"dbs": "cad_legenda_key",
"label": L("cad_legenda"),
"typ": "key",

108
APPL/API2/model_swagger.inc Normal file
View File

@@ -0,0 +1,108 @@
<% /*
$Revision$
$Id$
File: model_apis.inc
Description: Api model.
Parameters:
Context:
Notes:
*/
%>
<!--#include file="./api2_dispatch.inc"-->
<!-- #include file="./model_apis.inc" -->
<%
model_apis =
{
table: "apis",
primary: "id",
records_name: "swaggers",
record_name: "swagger",
fields : { "id" : { typ: "varchar", label: "Api", filter: "exact" },
"module" : { typ: "varchar", label: "Module", filter: "exact" },
"name" : { typ: "varchar", label: "Api", filter: "exact" }
},
formatted_get: true,
REST_GET: function _GET(params)
{
var autfunction = "WEB_APIDOC"; // is dit niet erg streng?
user.checkAutorisation(autfunction); // pessimistisch
var result = {
"swagger":"2.0",
"info":{
"description":"This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
"version":"1.0.0",
"title":"FACILITOR",
"termsOfService":"http://swagger.io/terms/",
"contact":{
"email":"info@facilitor.nl"
},
"license":{
"name":"Apache 2.0",
"url":"http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"host": String(Request.ServerVariables("SERVER_NAME")),
"basePath": rooturl + "/api2",
"schemes":[
"http"
],
"consumes":[
"application/json",
"application/xml"
],
"produces":[
"application/json",
"application/xml"
],
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "X-FACILITOR-API-Key",
"in": "header"
}
},
"paths":{}
};
result.tags = [];
var donetags = {};
for (var dispatch in api2_mapper)
{
if (api2_mapper[dispatch].hidden)
continue;
var filepath = api2_mapper[dispatch].filename;
var filename = filepath.split('/').pop();
var module = api2_mapper[dispatch].module || filename.substr(0, 3).toUpperCase();
if (!api2_mapper[dispatch].nodoc)
{
var trans = "&module={1}&fac_lang={2}".format(dispatch, module, getQParamSafe("fac_lang", user_lang));
result.paths["/" + dispatch + ".json"] =
{
"$ref": HTTP.urlzelf() + "/api2/{0}.api?swagger=1".format(dispatch) + trans
}
result.paths["/" + dispatch + "/{id}.json"] =
{
"$ref": HTTP.urlzelf() + "/api2/{0}.api?swagger=1&single=1".format(dispatch) + trans
}
}
if (donetags[module])
continue;
donetags[module] = true;
result.tags.push({ name: module, description: L("lcl_module_" + module) });
}
return result;
},
search: { autosearch: true },
list: { default_url: "api2/{0}.scf" }
// list: { default_url: "api2/{0}.api?pretty=1" }
}
%>