Rest protocols now make use of the http method to select the function is needed
This commit is contained in:
parent
3aa41ec7b1
commit
9d7b2895a5
@ -14,6 +14,8 @@ Changes
|
|||||||
|
|
||||||
* Tests code coverage is now over 95%.
|
* Tests code coverage is now over 95%.
|
||||||
|
|
||||||
|
* RESTful protocol can now use the http method.
|
||||||
|
|
||||||
0.3 (2012-04-20)
|
0.3 (2012-04-20)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -23,11 +23,14 @@ following paths :
|
|||||||
- ``/ws/persons/update``
|
- ``/ws/persons/update``
|
||||||
- ``/ws/persons/destroy``
|
- ``/ws/persons/destroy``
|
||||||
|
|
||||||
In a near future, an additional expose option `restverb` will allow
|
In addition to this trivial function mapping, a `method` option can
|
||||||
to use the HTTP verb to select the function, in which case the path
|
be given to the `expose` decorator. In such a case, the function
|
||||||
will not containt the function name.
|
name can be omitted by the caller, and the dispatch will look at the
|
||||||
|
http method used in the request to select the correct function.
|
||||||
|
|
||||||
The function parameters can be transmitted in two ways :
|
The function parameters can be transmitted in two ways (is using
|
||||||
|
the http method to select the function, one way or the other
|
||||||
|
may be usable) :
|
||||||
|
|
||||||
#. As a GET query string or POST form parameters.
|
#. As a GET query string or POST form parameters.
|
||||||
|
|
||||||
|
@ -24,6 +24,22 @@ class RestProtocol(Protocol):
|
|||||||
if path[-1].endswith('.' + self.dataformat):
|
if path[-1].endswith('.' + self.dataformat):
|
||||||
path[-1] = path[-1][:-len(self.dataformat) - 1]
|
path[-1] = path[-1][:-len(self.dataformat) - 1]
|
||||||
|
|
||||||
|
# Check if the path is actually a function, and if not
|
||||||
|
# see if the http method make a difference
|
||||||
|
# TODO Re-think the function lookup phases. Here we are
|
||||||
|
# doing the job that will be done in a later phase, which
|
||||||
|
# is sub-optimal
|
||||||
|
for p, fdef in self.root.getapi():
|
||||||
|
if p == path:
|
||||||
|
return path
|
||||||
|
|
||||||
|
# No function at this path. Now check for function that have
|
||||||
|
# this path as a prefix, and declared an http method
|
||||||
|
for p, fdef in self.root.getapi():
|
||||||
|
if len(p) == len(path) + 1 and p[:len(path)] == path and \
|
||||||
|
fdef.extra_options.get('method') == context.request.method:
|
||||||
|
return p
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def read_arguments(self, context):
|
def read_arguments(self, context):
|
||||||
@ -35,7 +51,7 @@ class RestProtocol(Protocol):
|
|||||||
request.headers['Content-Type']:
|
request.headers['Content-Type']:
|
||||||
# The params were read from the body, ignoring the body then
|
# The params were read from the body, ignoring the body then
|
||||||
pass
|
pass
|
||||||
elif len(request.params) and request.body:
|
elif len(request.params) and request.content_length:
|
||||||
log.warning("The request has both a body and params.")
|
log.warning("The request has both a body and params.")
|
||||||
log.debug("Params: %s" % request.params)
|
log.debug("Params: %s" % request.params)
|
||||||
log.debug("Body: %s" % request.body)
|
log.debug("Body: %s" % request.body)
|
||||||
|
@ -14,6 +14,7 @@ import wsme.protocols.restjson
|
|||||||
from wsme.protocols.restjson import fromjson, tojson
|
from wsme.protocols.restjson import fromjson, tojson
|
||||||
from wsme.utils import parse_isodatetime, parse_isotime, parse_isodate
|
from wsme.utils import parse_isodatetime, parse_isotime, parse_isodate
|
||||||
from wsme.types import isusertype, register_type
|
from wsme.types import isusertype, register_type
|
||||||
|
from wsme.api import expose, validate
|
||||||
|
|
||||||
|
|
||||||
import six
|
import six
|
||||||
@ -79,6 +80,52 @@ def prepare_result(value, datatype):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class Obj(wsme.types.Base):
|
||||||
|
id = int
|
||||||
|
name = wsme.types.text
|
||||||
|
|
||||||
|
|
||||||
|
class CRUDResult(object):
|
||||||
|
data = Obj
|
||||||
|
message = wsme.types.text
|
||||||
|
|
||||||
|
def __init__(self, data=wsme.types.Unset, message=wsme.types.Unset):
|
||||||
|
self.data = data
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
|
class MiniCrud(object):
|
||||||
|
@expose(CRUDResult, method='PUT')
|
||||||
|
@validate(Obj)
|
||||||
|
def create(self, data):
|
||||||
|
print(repr(data))
|
||||||
|
return CRUDResult(data, u('create'))
|
||||||
|
|
||||||
|
@expose(CRUDResult, method='GET')
|
||||||
|
@validate(Obj)
|
||||||
|
def read(self, ref):
|
||||||
|
print(repr(ref))
|
||||||
|
if ref.id == 1:
|
||||||
|
ref.name = u('test')
|
||||||
|
return CRUDResult(ref, u('read'))
|
||||||
|
|
||||||
|
@expose(CRUDResult, method='POST')
|
||||||
|
@validate(Obj)
|
||||||
|
def update(self, data):
|
||||||
|
print(repr(data))
|
||||||
|
return CRUDResult(data, u('update'))
|
||||||
|
|
||||||
|
@expose(CRUDResult, method='DELETE')
|
||||||
|
@validate(Obj)
|
||||||
|
def delete(self, ref):
|
||||||
|
print(repr(ref))
|
||||||
|
if ref.id == 1:
|
||||||
|
ref.name = u('test')
|
||||||
|
return CRUDResult(ref, u('delete'))
|
||||||
|
|
||||||
|
wsme.tests.protocol.WSTestRoot.crud = MiniCrud()
|
||||||
|
|
||||||
|
|
||||||
class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
||||||
protocol = 'restjson'
|
protocol = 'restjson'
|
||||||
|
|
||||||
@ -256,13 +303,6 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
|||||||
assert r[1] == '''{
|
assert r[1] == '''{
|
||||||
"a": 2
|
"a": 2
|
||||||
}''', r[1]
|
}''', r[1]
|
||||||
|
|
||||||
def test_encode_sample_result(self):
|
|
||||||
r = self.root.protocols[0].encode_sample_result(
|
|
||||||
int, 2, True
|
|
||||||
)
|
|
||||||
assert r[0] == 'javascript', r[0]
|
|
||||||
assert r[1] == '''2'''
|
|
||||||
|
|
||||||
def test_encode_sample_result(self):
|
def test_encode_sample_result(self):
|
||||||
r = self.root.protocols[0].encode_sample_result(
|
r = self.root.protocols[0].encode_sample_result(
|
||||||
@ -278,3 +318,63 @@ class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
|||||||
assert r[1] == '''{
|
assert r[1] == '''{
|
||||||
"result": 2
|
"result": 2
|
||||||
}'''
|
}'''
|
||||||
|
|
||||||
|
def test_PUT(self):
|
||||||
|
data = {"id": 1, "name": u("test")}
|
||||||
|
content = json.dumps(dict(data=data))
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
res = self.app.put(
|
||||||
|
'/crud',
|
||||||
|
content,
|
||||||
|
headers=headers,
|
||||||
|
expect_errors=False)
|
||||||
|
print("Received:", res.body)
|
||||||
|
result = json.loads(res.text)
|
||||||
|
print(result)
|
||||||
|
assert result['data']['id'] == 1
|
||||||
|
assert result['data']['name'] == u("test")
|
||||||
|
assert result['message'] == "create"
|
||||||
|
|
||||||
|
def test_GET(self):
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
res = self.app.get(
|
||||||
|
'/crud?ref.id=1',
|
||||||
|
headers=headers,
|
||||||
|
expect_errors=False)
|
||||||
|
print("Received:", res.body)
|
||||||
|
result = json.loads(res.text)
|
||||||
|
print(result)
|
||||||
|
assert result['data']['id'] == 1
|
||||||
|
assert result['data']['name'] == u("test")
|
||||||
|
assert result['message'] == "read"
|
||||||
|
|
||||||
|
def test_POST(self):
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
res = self.app.post(
|
||||||
|
'/crud',
|
||||||
|
json.dumps(dict(data=dict(id=1, name=u('test')))),
|
||||||
|
headers=headers,
|
||||||
|
expect_errors=False)
|
||||||
|
print("Received:", res.body)
|
||||||
|
result = json.loads(res.text)
|
||||||
|
print(result)
|
||||||
|
assert result['data']['id'] == 1
|
||||||
|
assert result['data']['name'] == u("test")
|
||||||
|
assert result['message'] == "update"
|
||||||
|
|
||||||
|
def test_DELETE(self):
|
||||||
|
res = self.app.delete(
|
||||||
|
'/crud.json?ref.id=1',
|
||||||
|
expect_errors=False)
|
||||||
|
print("Received:", res.body)
|
||||||
|
result = json.loads(res.text)
|
||||||
|
print(result)
|
||||||
|
assert result['data']['id'] == 1
|
||||||
|
assert result['data']['name'] == u("test")
|
||||||
|
assert result['message'] == "delete"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user