简单的类 Nova REST API 实现程序

正在看Nova API的代码, 仿照其中的REST 实现逻辑写了一个测试程序.

Nova API 当然支持了更多的功能, 例如XML/JSON序列化, 身份验证等等. 这个测试程序只实现其中的REST调用逻辑

为了容易读懂, 我去掉了其中的类继承逻辑

MyRouter: 负责把HTTP请求, 根据匹配规则, 分发到不同的Application中

1) [ Python Deploy ] 收到HTTP请求后, 先调用 MyRouter的 __call__方法进行处理

2) [ MyRouter ] 根据内部的匹配定义, 通过RouteMiddleware 分发到对应的 MyApplication

MyApplication: 收到HTTP 请求后, 解析其中的参数信息, 调用后台的MyController业务类的对应方法

MyController: 最终的业务类, 接受参数, 执行业务逻辑的操作.

from __future__ import print_function
from routes import Mapper
import webob.dec
import webob.exc
import routes.middleware
import testtools

class MyController(object):
    def getlist(self, mykey):
        print("step 4: MyController's getlist(self, mykey) is invoked")
        return "getlist(), mykey=" + mykey

class MyApplication(object):
    """Test application to call from router."""

    def __init__(self, controller):
        self._controller = controller

    def __call__(self, environ, start_response):
        print("step 3: MyApplication is invoked")

        action_args = environ['wsgiorg.routing_args'][1].copy()
        try:
            del action_args['controller']
        except KeyError:
            pass

        try:
            del action_args['format']
        except KeyError:
            pass

        action = action_args.pop('action', None)
        controller_method = getattr(self._controller, action)
        result = controller_method(**action_args)

        start_response('200 OK', [('Content-Type', 'text/plain')])
        return [result]

class MyRouter(object):
    """Test router."""

    def __init__(self):
        route_name = "dummy_route"
        route_path = "/dummies"

        my_application = MyApplication(MyController()) 

        self.mapper = Mapper()
        self.mapper.connect(route_name, route_path,
                        controller=my_application,
                        action="getlist",
                        mykey="myvalue",
                        conditions={"method": ['GET']})

        self._router = routes.middleware.RoutesMiddleware(self._dispatch,
                                                          self.mapper)

    @webob.dec.wsgify(RequestClass=webob.Request)
    def __call__(self, req):
        """Route the incoming request to a controller based on self.map.

        If no match, return a 404.

        """
        print("step 1: MyRouter is invoked")
        return self._router

    @staticmethod
    @webob.dec.wsgify(RequestClass=webob.Request)
    def _dispatch(req):
        """Dispatch the request to the appropriate controller.

        Called by self._router after matching the incoming request to a route
        and putting the information into req.environ.  Either returns 404
        or the routed WSGI app's response.

        """
        print("step 2: RoutesMiddleware is invoked, calling our _dispatch back")

        match_dict = req.environ['wsgiorg.routing_args'][1]
        if not match_dict:
            return webob.exc.HTTPNotFound()
        app = match_dict['controller']
        return app

class RoutingTestCase(testtools.TestCase):

    def test_router(self):
        router = MyRouter()
        result = webob.Request.blank('/dummies').get_response(router)
        self.assertEqual(result.body, "getlist(), mykey=myvalue")

从输出结果, 可以看出调用顺序是:  MyRouter --> routes.middleware.RoutesMiddleware --> MyApplication --> MyController:

[Test Case] test_router
step 1: MyRouter is invoked
step 2: RoutesMiddleware is invoked, calling our _dispatch back
step 3: MyApplication is invoked
step 4: MyController's getlist(self, mykey) is invoked

时间: 2024-10-27 17:37:56

简单的类 Nova REST API 实现程序的相关文章

如何在Web API应用程序中使用FastReport

下载FastReport.Net最新版本 在本文中,我们将创建一个用于从服务器接收FastReport报表的API.首先,让我们定义API是什么.从字面上看,这个缩写代表了应用程序的软件界面.这意味着应用程序具有提供对其功能的访问的接口.在Web应用程序的上下文中,API是一种Web服务,具有一组与后端(应用程序或数据库)交互的方法.换句话说,系统对我们来说是一个黑盒子,只有Web方法允许我们使用它. 因此,我们确定Web Api是一个带有一组Web方法的Web服务.这些可以是HTTP协议支持的

拿nodejs快速搭建简单Oauth认证和restful API server攻略

拿nodejs快速搭建简单Oauth认证和restful API server攻略:http://blog.csdn.net/zhaoweitco/article/details/21708955 最近一直在鼓捣这个东西,拿出来分享下一下经验吧,其实很简单,一点也不难. 首先需求是这样,给自己的网站要增加API服务,API分为两种,公共的和私有授权的,授权的使用Oauth方法认证身份,API格式均为JOSN和JSONP. 嗯,别的语言我也没怎么学过,首先是找合适的框架进行实现吧.本身网站使用的e

IIS8.5 布署 WEB API的程序时,遇到的问题

##IIS7/8 HTTP Error 500.19 错误 0x80070021  IIS7.0/8.0的错误HTTP Error 500.19 - Internal Server Error ,错误代码为0x80070021,大概原因为IIS7.0的安全设定相比前版本有很大的变更.IIS7.0的安全设置文件在%windir%\system32\inetsrv \config\applicationHost.config,这里定义所有Web程序的安全设置,在各个Web程序的web.config可

使用ActionContext类访问Servlet API

Struts2的action并未与Servlet API进行耦合,这是Struts2的一个改良,从而方便单独对Action进行测试. 但对于Web控制器而言,不访问Action是不行的,Struts提供了一种比较简单的方式访问Servlet API.通常 我们需要访问的Servlet API是HttpSession,HTTPservletRequest,ServletContext,分别对应JSP中内置 对象session,request,application. Struts2提供了Actio

在docker中运行ASP.NET Core Web API应用程序

本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Core以及docker的基本概念,网上已经有很多文章对其进行介绍了,因此本文不会再详细讲解这些内容.对.NET Core和docker不了解的朋友,建议首先查阅与这些技术相关的文档,然后再阅读本文. 先决条件 要完成本文所介绍的演练任务,需要准备以下环境: Visual Studio 2015,或者Vi

非计算机类专业毕业生五年程序员职业生涯的回顾和思考

0.前言看到过几篇程序员的职业生涯过程,我也来当一回写手吧,希望对和我一样曾经磕磕碰碰过的人有帮助.谨以此文纪念大学毕业五周年,传播一些正能量. 1.从校园启程我的大学专业全称是无机非金属材料工程,这专业多与玻璃.水泥.陶瓷打交道,高大上一点的是各种珠宝,前沿一点的是纳米材料.想先声明的是,我不是在黑自己的专业,只是每个人都会有自己喜欢和适合自己的工作和生活状态.我尝试过为了完成一个程序而废寝忘食后就爱上了这个职业,即使知道这是个加班如家常便饭的工作也义无反顾.而且后来我发现材料工程的学习经历并

Java基础_3.5:简单Java类

简单Java类 简单Java类是一种在实际开发之中使用最多的类的定义形式,在简单Java类中包含有类.对象.构造方法.private封装等核心概念的使用,而对于简单Java类首先给出如下的基本开发要求: 类名称必须存在有意义,例如:Book.Emp: 类之中所有的属性必须private封装,封装后的属性必须提供有setter.getter: 类之中可以提供有任意多个构造方法,但是必须保留有一个无参构造方法: 类之中不允许出现任何的输出语句,所有信息输出必须交给被调用处输出: 类之中需要提供有一个

简单Java类 全网最详细讲解 !!!

最近学习java非常吃力,学习的进度很快,由于基础没打牢固,整体上项目理解很吃力,偶尔会遇到一些基本的概念,都会阻碍整体的理解.最近也看了不少的视频讲解,听得很迷,最后搞得很乱,没有明确的学习目标,今天翻了翻书本,看到里面讲的很细,然后恍然大悟.话不多说,自己再整体的梳理一遍. 首先,下面列出关键词:类  属性  方法  对象  实例化对象  构造方法  初始化  局部变量  成员变量    之前每次遇到这些关键词,头都大了. 接下来我一点一点的讲: 1.什么是类: 定义:表示一个客观世界中某类

java反射(四)--反射与简单java类

一.传统简单java类 简单的java类主要是由属性所组成,并且提供有相应的setter以及getter的处理方法,同时简单java类最大的特征就是通过对象保存相应的类的属性内容,但是如果使用传统的简单java类的开发,那么也会面临非常麻烦的困难: 1 class Emp{ 2 private String ename; 3 private String job; 4 5 public void setEname(String ename) { 6 this.ename = ename; 7 }