2

I have a Django web application, which allows users to do stop/start/install_pkg on a remote server over HTTP from UI. Django web app has start / stop / install_pkg functions already implemented which basically creates the appropriate URL and calls the HTTP url with params.

My goal is to use the same internal functions when user does a REST call like the following:

1. https://api/v1/server/<server_name>/start/?api_key=<api_key>&params=<params>
2. https://api/v1/server/<server_name>/stop/?api_key=<api_key>&params=<params>
3. https://api/v1/server/<server_name>/install_pkg/?api_key=<api_key>&params=<params>

And return JSON response to the caller containing remote server response object.

So far I have used Tastypie library to expose read-only access to model data of the Django web app over REST.

Tastypie tutorial on Non ORM resource shows how to interact with non ORM resources by overriding 9 methods of Tastypie. But given my limited knowledge and understanding I am unclear about how to use Tastypie for my case. Am I missing anything here?

EDITED: (29 Oct 2012)

To clarify further - Django web app has ORM entry for each of the remote servers in but this information is static info about a particular remote server like (name, ip, domain, ...) since it is created at the time of registering the remote server to Django web app.

The web service call from the Django web app to the remote server fetches the most current state of the remote server like (app_state, pkg_installed_list, ...) and this data is not getting stored anywhere in my Djnago web app. It is rendered as it is in UI.

Thus a GET on Django web app about the remote server essentially returns the static info.

Thanks,

4

1 回答 1

8

一种方法是只跟踪服务器资源,并将 start/stop/install_pkg 实现为自定义端点。

您将在 Tastypie 下实现服务器资源,以便使用常规的基于 ORM 的资源为每个服务器提供端点。这实现了对资源的标准 REST 操作,GET 来读取服务器信息,POST 来创建新的,如果你说你有管理员用户需要添加另一个服务器来管理它的服务,PUT/PATCH 来更新现有的服务器。

然后,您将通过以下方式扩展 ServerResource 以包含其他端点:

  1. 用于prepend_urls定义 3 个自定义端点(start、stop、install_pkg)
  2. 在 ServerResource 下的函数中实现每个端点,注意考虑安全性、限制操作(您希望在它们上调用 GET 或 POST 吗?)

另一种方法是将 ServiceResource 创建为非 ORM 资源,它将与服务器资源有多对多的关系。这是更棘手但可以说是更清洁的设计。

您的 ServiceResource 将有 2 个自定义端点,就像在前面的场景(启动/停止)中一样,但是要在服务器上安装服务,您需要将 PUT/PATCH 发送到要与该服务关联的 ServerResource。

如需更具体的答案,请说明更具体的问题。


有关如何进行的一些可靠细节,请参阅 Tastypie 食谱:

搜索示例使用override_urls您要在 0.9.11 中使用的内容,并且与prepend_urls尚未发布的 0.9.12 具有相似的行为。根据您使用的版本,您需要创建 3 个自定义端点:

 def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%start%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('start'), name="api_start"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%stop%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('stop'), name="api_stop"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%install_pkg%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('install_pkg'), name="api_install_pkg"),
        ]

然后,您需要定义类似于 ServerResource 上的搜索示例的 3 个处理程序。我会给你一个 start 函数的起点。这是一个同步操作的例子。如果您希望它是异步的,您将需要更多,但这是一个起点。

from tastypie.http import Http

def start(self, request, **kwargs):
    self.method_check(request, allowed=['post'])
    self.is_authenticated(request)
    self.throttle_check(request)

    try:
        output = function_that_starts_server(kwargs['pk'])
    except FailedException as failure:
        return self.create_response(request, { 'status' : 'failure', 'reason' : failure }, Http

    self.log_throttled_access(request)
    return self.create_response(request, { 'status' : 'success', 'log' : output })
于 2012-10-27T02:42:33.853 回答