来自spyne.io的示例:
class HelloWorldService(ServiceBase):
@srpc(Unicode, Integer, _returns=Iterable(Unicode))
def say_hello(name, times):
for i in range(times):
yield 'Hello, %s' % name
application = Application([HelloWorldService],
tns='spyne.examples.hello',
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument()
)
这意味着被调用的方法名称必须是JSON正文的唯一键:
$ curl -s http://localhost:8000/ -d '{"say_hello": {"name": "World", "times": 5}}'
我希望正文不包含方法名称,但是要从URL中获取方法名称,就像使用HttpRpc一样:
$ curl -s http://localhost:8000/say_hello -d '{"name": "World", "times": 5}'
如何定义服务以处理此类请求?
答案 0 :(得分:1)
您可以从JsonDocument
派生新的协议类型。您只需要重写一个方法:
# Tested with spyne.__version__=='2.10.9'
class warwarukDocument(JsonDocument):
"""An implementation of the json protocol
with the method name stored in the URL,
not the document."""
def create_in_document(self, ctx, in_string_encoding=None):
""" Sets ``ctx.in_document`` using ``ctx.in_string``."""
assert ctx.transport.type.endswith('http'), \
"This protocol requires an http transport, not %r (in %r)" \
% (ctx.transport.type, ctx.transport)
super(warwarukDocument, self).create_in_document(ctx, in_string_encoding)
# Not 100% sure where to find the URL path
try:
# Works for twisted
uri = ctx.transport.req.uri
except AttributeError:
# Works for WSGI
uri = ctx.transport.req['PATH_INFO']
uri = re.sub(r'.*/', '', uri)
ctx.in_document = { uri : ctx.in_document }
application = Application([HelloWorldService],
tns='spyne.examples.hello',
in_protocol=warwarukDocument(validator='soft'),
out_protocol=JsonDocument()
)
用法:
$ curl -s http://localhost:8000/say_hello \
-d '{"name": "World", "times": 1}' | python -m json.tool
[
"Hello, World"
]
$ curl -s http://localhost:8000/say_goodbye \
-d '{"name": "World", "times": 1}' | python -m json.tool
{
"detail": null,
"faultcode": "Client.ResourceNotFound",
"faultstring": "Requested resource \"Method u'{spyne.examples.hello}say_goodbye' not found.\" not found"
}