RESTful

展开目录
RESTful
  对于现在主流的RESTful Web Service,Pecan有两个方法来实现。
  第一种方法是使用普通的Controller来实现。以student这种资源为例,首先需要定义类StudentController以管理单个student;然后定义类Students以批量管理多个students,需要在方法_lookup()中引用StudentController;最后在RootController中创建Students的实例。具体代码如下:

from pecan import expose

from pecan import abort

STUDENTS = {
    '0': 'John',
    '1': 'Lucy'
}

class StudentController(object):

    def __init__(self, id_):
        self.id_ = id_
        assert self.student

    @property
    def student(self):
        if self.id_ in STUDENTS:
            return dict(id=self.id_, name=STUDENTS[self.id_])
        abort(404)

    # HTTP GET //
    @expose(generic=True, template='json')
    def index(self):
        return self.student

    # HTTP PUT //
    @index.when(method='PUT', template='json')
    def index_PUT(self, **kw):
        STUDENTS[self.id_] = kw['name']
        return self.student

    # HTTP DELETE //
    @index.when(method='DELETE', template='json')
    def index_DELETE(self):
        del STUDENTS[self.id_]
        return dict()


class Students(object):

    @expose()
    def _lookup(self, id_, *remainder):
        return StudentController(id_), remainder

    # HTTP GET /
    @expose(generic=True, template='json')
    def index(self):
        return [dict(id=k, name=v) for k, v in STUDENTS.items()]

    # HTTP POST /
    @index.when(method='POST', template='json')
    def index_POST(self, **kw):
        print('kw: %r' % kw)
        id_ = str(len(STUDENTS))
        STUDENTS[id_] = kw['name']
        return dict(id=id_, name=kw['name'])


class RootController(object):
    students = Students()

  可以使用curl来验证:

[root@www.fmttr.com ~]# curl http://127.0.0.1:8080/students/
[{"name": "Lucy", "id": "1"}, {"name": "John", "id": "0"}]

[root@www.fmttr.com ~]# curl -X POST -H "Content-Type: application/json" -d '{"name": "Trump"}' http://127.0.0.1:8080/students/
{"name": "Trump", "id": "2"}

[root@www.fmttr.com ~]# curl http://127.0.0.1:8080/students/
[{"name": "Lucy", "id": "1"}, {"name": "John", "id": "0"}, {"name": "Trump", "id": "2"}]

  以上的三个命令,第一个命令,通过HTTP的GET请求获取了所有的student信息;第二命令,通过HTTP的POST命令创建了一个新的student,名称name为"Trump";第三个命令,再次过HTTP的GET请求获取了所有的student信息。可以看到第二个命令创建的student已经出现在第三个命令的输出中。
  可以看到第一种实现RESTful Web Service的方法比较繁杂,为此,Pecan提供了类RestController,以简化RESTful的实现。RestController已经实现了RESTfull相关的url映射,使用RestController实现RESTfull,只需从其派生出新类,并实现预定的方法即可。具体代码如下:

from pecan import expose
from pecan.rest import RestController


STUDENTS = {
    '0': 'John',
    '1': 'Lucy'
}

class StudentController(RestController):

    @expose(generic=True, template='json')
    def get_all(self):
        return [dict(id=k, name=v) for k, v in STUDENTS.items()]

    # HTTP GET //
    @expose(generic=True, template='json')
    def get(self, id):
        print('get(%s)' % id)
        for key, name in STUDENTS.items():
            if key == id:
                s = dict(id=key, name=name)
                break;
        else:
            s = None
        return s


class RootController(object):

    students = StudentController()

  以上代码作为示例,只实现了GET /students/和GET /students/。可以使用curl进行验证:

[root@www.fmttr.com ~]# curl http://127.0.0.1:8080/students/
[{"name": "Lucy", "id": "1"}, {"name": "John", "id": "0"}]

[root@www.fmttr.com ~]# curl http://127.0.0.1:8080/students/1
{"name": "Lucy", "id": "1"}

  根据需要可以实现其它的RESTfull方法。完整的url映射以下表所示:

方法名HTTP方法 url描述
get_oneGET /students/1获取一个记录
get_allGET /students/获取所有记录
getGET /students/组合get_one和get_all
newGET /students/new获取创建一个新记录的页面
editGET /students/1/EDIT获取编辑一条记录的页面
postPOST /students/创建一条记录
putput /students/1更新一条记录
get_deleteGET /students/1/delete获取删除一条记录的页面
deletePOST /students/1删除一条记录