扩展Admin API
本文原文:https://docs.konghq.com/1.1.x/plugin-development/admin-api/
注意:本章假设您具有Lapis的相关知识。
简介
可以使用被称为Admin API的REST接口配置Kong。插件可以通过添加自己的路径来扩展它,以适应自定义实体或其他个性化管理需求。典型的例子是API密钥的创建,查找和删除(通常称为“CRUD操作”)。
Admin API是Lapis应用程序,Kong的抽象级别使您可以轻松添加路径。
Module
kong.plugins.<plugin_name>.api
将路径添加到Admin API
如果在名为的模块中定义路径,Kong将检测并加载路径:
"kong.plugins.<plugin_name>.api"
该模块必须返回一个包含一个或多个属性的表,其结构如下:
{["<path>"] = {schema = <schema>,methods = {before = function(self) ... end,on_error = function(self) ... end,GET = function(self) ... end,PUT = function(self) ... end,...}},...}
其中:
<path>应该是一个表示像/users这样的路由的字符串(请参阅Lapis路由和URL模式)以获取详细信息。请注意,路径可以包含插值参数,类似/users/:users/new。<schema>是架构定义。核心和自定义插件实体的schema可通过kong.db.<entity>.schema。schema用于根据类型解析某些字段;例如,如果一个字段被标记为一个整数,它将被传递给一个函数时被解析(默认表单字段都是字符串)。methods子表包含由字符串索引的函数。before键是可选的,可以保存一个函数。如果存在,则在调用任何其他函数之前,将对每个命中路径的请求执行该函数。- 可以使用HTTP方法名称(如
GET或PUT)索引一个或多个函数。匹配适当的HTTP方法和路径时,将执行这些函数。如果路径上存在before函数,则首先执行该函数。请记住,before函数可以使用kong.response.exit来提前完成。有效地取消了“常规”http方法功能。 on_error键是可选的,可以保存一个函数。如果存在,当来自其他函数的代码(来自之前或“http方法”)抛出错误时,将执行该函数。如果不存在,那么Kong将使用默认错误处理程序来返回错误。
例如:
local endpoints = require "kong.api.endpoints"local credentials_schema = kong.db.keyauth_credentials.schemalocal consumers_schema = kong.db.consumers.schemareturn {["/consumers/:consumers/key-auth"] = {schema = credentials_schema,methods = {GET = endpoints.get_collection_endpoint(credentials_schema, consumers_schema, "consumer"),POST = endpoints.post_collection_endpoint(credentials_schema, consumers_schema, "consumer"),},},}
此代码将在/consumers/:consumers/key-auth中创建两个Admin API路径。获取(GET)和创建(POST)与给定使用者相关联的凭证。在此示例中,函数由kong.api.endpoints库提供。如果您想查看更完整的示例,并在函数中使用自定义代码,请参阅key-auth插件中的api.lua文件。
endpoints模块当前包含Kong中最常用的CRUD操作的基本实现。此模块为您提供任何插入,查询,更新或删除操作的帮助程序,并执行必要的DAO操作并使用相应的HTTP状态代码进行回复。它还为您提供从路径中查询参数的功能,例如 Service的名称或ID,或Consumer的用户名或ID。
如果提供的endpoints功能不够,则可以使用常规的Lua函数。
从那里你可以使用:
endpoints模块提供的几个功能。- PDK提供的所有功能
self参数,即Lapis请求对象。- 当然,如果需要,您可以
require任何Lua模块。如果选择此方法,请确保它们与OpenResty兼容。
local endpoints = require "kong.api.endpoints"local credentials_schema = kong.db.keyauth_credentials.schemalocal consumers_schema = kong.db.consumers.schemareturn {["/consumers/:consumers/key-auth/:keyauth_credentials"] = {schema = credentials_schema,methods = {before = function(self, db, helpers)local consumer, _, err_t = endpoints.select_entity(self, db, consumers_schema)if err_t thenreturn endpoints.handle_error(err_t)endif not consumer thenreturn kong.response.exit(404, { message = "Not found" })endself.consumer = consumerif self.req.method ~= "PUT" thenlocal cred, _, err_t = endpoints.select_entity(self, db, credentials_schema)if err_t thenreturn endpoints.handle_error(err_t)endif not cred or cred.consumer.id ~= consumer.id thenreturn kong.response.exit(404, { message = "Not found" })endself.keyauth_credential = credself.params.keyauth_credentials = cred.idendend,GET = endpoints.get_entity_endpoint(credentials_schema),PUT = function(self, db, helpers)self.args.post.consumer = { id = self.consumer.id }return endpoints.put_entity_endpoint(credentials_schema)(self, db, helpers)end,},},}
在前面的例子中,/consumers/:consumers/key-auth/:keyauth_credentials路径有三个功能:
- before函数是一个自定义Lua函数,它使用多个
endpoints提供的实用程序(endpoints.handle_error)以及PDK函数(kong.response.exit)。它还会填充self.consumer以供后续使用的函数使用。 - GET功能完全使用
endpoints构建。这是可能的,因为之前已经预先“准备好”了东西,比如self.consumer。 - PUT函数在调用
endpoints提供的put_entity_endpoint函数之前填充self.args.post.consumer。
下一步:为你的插件编写单元测试
