local lapis = require "lapis" local api_helpers = require "kong.api.api_helpers" local Endpoints = require "kong.api.endpoints" local hooks = require "kong.hooks" local load_module_if_exists = require "kong.tools.module".load_module_if_exists local ngx = ngx local type = type local pairs = pairs local ipairs = ipairs local app = lapis.Application() app.default_route = api_helpers.default_route app.handle_404 = api_helpers.handle_404 app.handle_error = api_helpers.handle_error app:before_filter(api_helpers.cors_filter) app:before_filter(api_helpers.before_filter) assert(hooks.run_hook("api:init:pre", app)) ngx.log(ngx.DEBUG, "Loading Admin API endpoints") -- Load core routes for _, v in ipairs({"kong", "health", "cache", "config", "debug", }) do local routes = require("kong.api.routes." .. v) api_helpers.attach_routes(app, routes) end -- Load custom DB routes for _, v in ipairs({"clustering", }) do local routes = require("kong.api.routes." .. v) api_helpers.attach_new_db_routes(app, routes) end do -- This function takes the auto-generated routes and then customizes them -- based on custom_endpoints. It will add one argument to actual function -- call `parent` that the customized function can use to call the original -- auto-generated function. -- -- E.g. the `/routes/:routes` API gets autogenerated from `routes` DAO. -- Now if your plugin adds `api.lua` that also defines the same endpoint: -- `/routes/:routes`, it means that the plugin one overrides the original -- function. Original is kept and passed to the customized function as an -- function argument (of course usually plugins want to only customize -- the autogenerated endpoints the plugin's own DAOs introduced). local function customize_routes(routes, custom_endpoints, schema) for route_pattern, verbs in pairs(custom_endpoints) do if type(verbs) == "table" then local methods = verbs.methods or verbs if routes[route_pattern] == nil then routes[route_pattern] = { schema = verbs.schema or schema, methods = methods } else for method, handler in pairs(methods) do local parent = routes[route_pattern]["methods"][method] if parent ~= nil and type(handler) == "function" then routes[route_pattern]["methods"][method] = function(self, db, helpers) return handler(self, db, helpers, function(post_process) return parent(self, db, helpers, post_process) end) end else routes[route_pattern]["methods"][method] = handler end end end end end end local routes = {} -- DAO Routes for _, dao in pairs(kong.db.daos) do if dao.schema.generate_admin_api ~= false then routes = Endpoints.new(dao.schema, routes) end end -- Custom Routes for _, dao in pairs(kong.db.daos) do local schema = dao.schema local ok, custom_endpoints = load_module_if_exists("kong.api.routes." .. schema.name) if ok then customize_routes(routes, custom_endpoints, schema) end end -- Plugin Routes if kong.configuration and kong.configuration.loaded_plugins then for k in pairs(kong.configuration.loaded_plugins) do local loaded, custom_endpoints = load_module_if_exists("kong.plugins." .. k .. ".api") if loaded then ngx.log(ngx.DEBUG, "Loading API endpoints for plugin: ", k) if api_helpers.is_new_db_routes(custom_endpoints) then customize_routes(routes, custom_endpoints, custom_endpoints.schema) else api_helpers.attach_routes(app, custom_endpoints) end else ngx.log(ngx.DEBUG, "No API endpoints loaded for plugin: ", k) end end end assert(hooks.run_hook("api:init:post", app, routes)) api_helpers.attach_new_db_routes(app, routes) end return app