扩展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

  1. kong.plugins.<plugin_name>.api

将路径添加到Admin API

如果在名为的模块中定义路径,Kong将检测并加载路径:

  1. "kong.plugins.<plugin_name>.api"

该模块必须返回一个包含一个或多个属性的表,其结构如下:

  1. {
  2. ["<path>"] = {
  3. schema = <schema>,
  4. methods = {
  5. before = function(self) ... end,
  6. on_error = function(self) ... end,
  7. GET = function(self) ... end,
  8. PUT = function(self) ... end,
  9. ...
  10. }
  11. },
  12. ...
  13. }

其中:

  • <path> 应该是一个表示像/users这样的路由的字符串(请参阅Lapis路由和URL模式)以获取详细信息。请注意,路径可以包含插值参数,类似/users/:users/new
  • <schema> 是架构定义。核心和自定义插件实体的schema可通过kong.db.<entity>.schema。schema用于根据类型解析某些字段;例如,如果一个字段被标记为一个整数,它将被传递给一个函数时被解析(默认表单字段都是字符串)。
  • methods子表包含由字符串索引的函数。
    • before键是可选的,可以保存一个函数。如果存在,则在调用任何其他函数之前,将对每个命中路径的请求执行该函数。
    • 可以使用HTTP方法名称(如GETPUT)索引一个或多个函数。匹配适当的HTTP方法和路径时,将执行这些函数。如果路径上存在before函数,则首先执行该函数。请记住,before函数可以使用kong.response.exit来提前完成。有效地取消了“常规”http方法功能。
    • on_error键是可选的,可以保存一个函数。如果存在,当来自其他函数的代码(来自之前或“http方法”)抛出错误时,将执行该函数。如果不存在,那么Kong将使用默认错误处理程序来返回错误。

例如:

  1. local endpoints = require "kong.api.endpoints"
  2. local credentials_schema = kong.db.keyauth_credentials.schema
  3. local consumers_schema = kong.db.consumers.schema
  4. return {
  5. ["/consumers/:consumers/key-auth"] = {
  6. schema = credentials_schema,
  7. methods = {
  8. GET = endpoints.get_collection_endpoint(
  9. credentials_schema, consumers_schema, "consumer"),
  10. POST = endpoints.post_collection_endpoint(
  11. credentials_schema, consumers_schema, "consumer"),
  12. },
  13. },
  14. }

此代码将在/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兼容。
  1. local endpoints = require "kong.api.endpoints"
  2. local credentials_schema = kong.db.keyauth_credentials.schema
  3. local consumers_schema = kong.db.consumers.schema
  4. return {
  5. ["/consumers/:consumers/key-auth/:keyauth_credentials"] = {
  6. schema = credentials_schema,
  7. methods = {
  8. before = function(self, db, helpers)
  9. local consumer, _, err_t = endpoints.select_entity(self, db, consumers_schema)
  10. if err_t then
  11. return endpoints.handle_error(err_t)
  12. end
  13. if not consumer then
  14. return kong.response.exit(404, { message = "Not found" })
  15. end
  16. self.consumer = consumer
  17. if self.req.method ~= "PUT" then
  18. local cred, _, err_t = endpoints.select_entity(self, db, credentials_schema)
  19. if err_t then
  20. return endpoints.handle_error(err_t)
  21. end
  22. if not cred or cred.consumer.id ~= consumer.id then
  23. return kong.response.exit(404, { message = "Not found" })
  24. end
  25. self.keyauth_credential = cred
  26. self.params.keyauth_credentials = cred.id
  27. end
  28. end,
  29. GET = endpoints.get_entity_endpoint(credentials_schema),
  30. PUT = function(self, db, helpers)
  31. self.args.post.consumer = { id = self.consumer.id }
  32. return endpoints.put_entity_endpoint(credentials_schema)(self, db, helpers)
  33. end,
  34. },
  35. },
  36. }

在前面的例子中,/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

下一步:为你的插件编写单元测试