diff --git a/Documentation/Books/Users/Foxx/Develop/ApiDocumentation.mdpp b/Documentation/Books/Users/Foxx/Develop/ApiDocumentation.mdpp new file mode 100644 index 0000000000..b052058f1f --- /dev/null +++ b/Documentation/Books/Users/Foxx/Develop/ApiDocumentation.mdpp @@ -0,0 +1,9 @@ +!CHAPTER Foxx API Documentation + +In addition to viewing the API documentation of any Foxx app in the admin frontend, you can also mount the API +documentation inside your own Foxx app. This allows you to serve your documentation to users without having to +give them access to the admin frontend or any other parts of ArangoDB. + +!SECTION Mounting the API documentation + +@startDocuBlock JSF_foxx_controller_apiDocumentation \ No newline at end of file diff --git a/Documentation/Books/Users/NewFeatures/NewFeatures26.mdpp b/Documentation/Books/Users/NewFeatures/NewFeatures26.mdpp new file mode 100644 index 0000000000..f0d11bb022 --- /dev/null +++ b/Documentation/Books/Users/NewFeatures/NewFeatures26.mdpp @@ -0,0 +1,12 @@ +!CHAPTER Features and Improvements + +The following list shows in detail which features have been added or improved in +ArangoDB 2.6. ArangoDB 2.6 also contains several bugfixes that are not listed +here. For a list of bugfixes, please consult the [CHANGELOG](https://github.com/arangodb/arangodb/blob/devel/CHANGELOG). + + +!SECTION Foxx Configuration + +!SECTION Foxx Dependencies + +!SECTION Foxx API Documentation \ No newline at end of file diff --git a/Documentation/Books/Users/SUMMARY.md b/Documentation/Books/Users/SUMMARY.md index afabaa16c7..aaa52ab1f3 100644 --- a/Documentation/Books/Users/SUMMARY.md +++ b/Documentation/Books/Users/SUMMARY.md @@ -113,6 +113,7 @@ * [Background Tasks](Foxx/Develop/Queues.md) * [Console API](Foxx/Develop/Console.md) * [Metainformation](Foxx/Develop/Manifest.md) + * [Documentation](Foxx/Develop/ApiDocumentation.md) * [Production](Foxx/Production/README.md) * [Prod-Mode](Foxx/Production/Productionmode.md) * [Debugging](Foxx/Production/Debugging.md) diff --git a/js/server/modules/org/arangodb/foxx/controller.js b/js/server/modules/org/arangodb/foxx/controller.js index 180c3657a7..dfd9343cf9 100644 --- a/js/server/modules/org/arangodb/foxx/controller.js +++ b/js/server/modules/org/arangodb/foxx/controller.js @@ -753,7 +753,63 @@ extend(Controller.prototype, { //////////////////////////////////////////////////////////////////////////////// /// @startDocuBlock JSF_foxx_controller_apiDocumentation /// -/// `FoxxController#apiDocumentation(path, opts)` +/// `FoxxController#apiDocumentation(path, [opts])` +/// +/// Mounts the API documentation (Swagger) at the given *path*. +/// +/// Note that the **path** can use URL parameters as usual but must not use any +/// wildcard (`*`) or optional (`:name?`) parameters. +/// +/// The optional **opts** can be an object with any of the following properties: +/// +/// * **before**: a function that will be executed before a request to +/// this endpoint is processed further. +/// * **appPath**: the mount point of the app for which documentation will be +/// shown. Default: the mount point of the active app. +/// * **indexFile**: file path or file name of the Swagger HTML file. +/// Default: `"index.html"`. +/// * **swaggerJson**: file path or file name of the Swagger API description JSON +/// file or a function `swaggerJson(req, res, opts)` that sends a Swagger API +/// description in JSON. Default: the built-in Swagger description generator. +/// * **swaggerRoot**: absolute path that will be used as the path path for any +/// relative paths of the documentation assets, **swaggerJson** file and +/// the **indexFile**. Default: the built-in Swagger distribution. +/// +/// If **opts** is a function, it will be used as the value of **opts.before**. +/// +/// If **opts.before** returns `false`, the request will not be processed +/// further. +/// +/// If **opts.before** returns an object, any properties will override the +/// equivalent properties of **opts** for the current request. +/// +/// Of course all **before**, **after** or **around** functions defined on the +/// controller will also be executed as usual. +/// +/// **Examples** +/// +/// ```js +/// controller.apiDocumentation('/my/dox'); +/// +/// ``` +/// +/// A request to `/my/dox` will be redirect to `/my/dox/index.html`, +/// which will show the API documentation of the active app. +/// +/// ```js +/// controller.apiDocumentation('/my/dox', function (req, res) { +/// if (!req.session.get('uid')) { +/// res.status(403); +/// res.json({error: 'only logged in users may see the API'}); +/// return false; +/// } +/// return {appPath: req.parameters.mount}; +/// }); +/// ``` +/// +/// A request to `/my/dox/index.html?mount=/_admin/aardvark` will show the +/// API documentation of the admin frontend (mounted at `/_admin/aardvark`). +/// If the user is not logged in, the error message will be shown instead. /// /// @endDocuBlock //////////////////////////////////////////////////////////////////////////////// @@ -766,11 +822,11 @@ extend(Controller.prototype, { }, //////////////////////////////////////////////////////////////////////////////// -/// @startDocuBlock JSF_foxx_controller_destroySession +/// @startDocuBlock JSF_foxx_controller_extend /// /// `FoxxController#extend(extensions)` /// -/// @EXAMPLES +/// **Examples** /// /// @endDocuBlock //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/modules/org/arangodb/foxx/swagger.js b/js/server/modules/org/arangodb/foxx/swagger.js index 153281f1e4..6583b09fc8 100644 --- a/js/server/modules/org/arangodb/foxx/swagger.js +++ b/js/server/modules/org/arangodb/foxx/swagger.js @@ -69,14 +69,19 @@ function createSwaggerRouteHandler(appPath, opts) { } if (pathInfo === 'swagger.json') { var swaggerJsonHandler = opts.swaggerJson || swaggerJson; - swaggerJsonHandler(req, res, {appPath: result ? result.appPath : (opts.appPath || appPath)}); - return; + if (typeof swaggerJsonHandler === 'string') { + pathInfo = swaggerJsonHandler; + } else if (typeof swaggerJsonHandler === 'function') { + swaggerJsonHandler(req, res, {appPath: result ? result.appPath : (opts.appPath || appPath)}); + return; + } + } else if (pathInfo === 'index.html') { + var indexFile = result ? result.indexFile : opts.indexFile; + if (indexFile) { + pathInfo = indexFile; + } } - var indexFile = result ? result.indexFile : opts.indexFile; - if (pathInfo === 'index.html' && indexFile) { - pathInfo = indexFile; - } - var path = fs.safeJoin(ArangoServerState.javaScriptPath(), 'server/assets/swagger', pathInfo); + var path = swaggerPath(pathInfo, result ? result.swaggerRoot : opts.swaggerRoot); if (!fs.isFile(path)) { resultNotFound(req, res, 404, "unknown path '" + req.url + "'"); return; @@ -85,6 +90,16 @@ function createSwaggerRouteHandler(appPath, opts) { }; } +function swaggerPath(path, basePath) { + if (path.charAt(0) === '/') { + return path; + } + if (!basePath) { + basePath = fs.safeJoin(ArangoServerState.javaScriptPath(), 'server/assets/swagger'); + } + return fs.safeJoin(basePath, path); +} + function swaggerJson(req, res, opts) { var foxx = FoxxManager.routes(opts.appPath); var app = foxx.appContext.app;