Commit 37c45a3b authored by Jacek Furmankiewicz's avatar Jacek Furmankiewicz

docs for argument parsing

parent a7a26a6a
......@@ -12,15 +12,11 @@ from corepost.convert import convertForSerialization, generateXml
from corepost.filters import IRequestFilter, IResponseFilter
from enums import MediaType
from twisted.internet import reactor, defer
from twisted.internet import defer
from twisted.web.http import parse_qs
from twisted.web.resource import Resource
from twisted.web.server import Site, NOT_DONE_YET
from twisted.python import log
import re, copy, exceptions, json, yaml, logging
from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from zope.interface.verify import verifyObject
class UrlRouter:
''' Common class for containing info related to routing a request to a function '''
......
......@@ -28,6 +28,10 @@ class ArgumentApp():
def postValidateCustom(self,request,rootId,childId,**kwargs):
return "%s - %s - %s" % (rootId,childId,kwargs)
@route("/formOrJson",Http.GET)
def getArgumentsByContentType(self,request,first,last,**kwargs):
return "%s %s" % (str(first),str(last))
@route("/formOrJson",(Http.POST,Http.PUT))
def postArgumentsByContentType(self,request,first,last,**kwargs):
return "%s %s" % (str(first),str(last))
......
......@@ -105,3 +105,9 @@ last: Gingrychnoya
| POST | 201 |
| PUT | 200 |
@arguments_by_type
Scenario: Parse query arguments for GET
Given 'arguments' is running
When as user 'None:None' I GET 'http://127.0.0.1:8082/formOrJson?first=John&last=Doe'
Then I expect HTTP code 200
And I expect content contains 'John Doe'
Asynchronous Operations
=================
=======================
@defer.inlineCallbacks support
-----------------------
------------------------------
If you want a deferred async method, just use *defer.returnValue()*::
......
......@@ -16,9 +16,11 @@ Features
:maxdepth: 4
url_routing
argument_parsing
arguments
content_types
filters
http_codes
async
modules
......@@ -42,7 +42,7 @@ based on URL (with dynamic paths), HTTP method, expected content type, etc::
* http://twistedmatrix.com/documents/current/core/howto/tap.html
Path argument extraction
----------------
------------------------
CorePort can easily extract path arguments from an URL and convert them to the desired type.
......
......@@ -27,7 +27,7 @@
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Content types" href="content_types.html" />
<link rel="prev" title="URL Routing" href="url_routing.html" />
<link rel="prev" title="Argument parsing" href="argument_parsing.html" />
</head>
<body>
<div class="related">
......@@ -40,7 +40,7 @@
<a href="content_types.html" title="Content types"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="url_routing.html" title="URL Routing"
<a href="argument_parsing.html" title="Argument parsing"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......@@ -95,8 +95,8 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="url_routing.html"
title="previous chapter">URL Routing</a></p>
<p class="topless"><a href="argument_parsing.html"
title="previous chapter">Argument parsing</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="content_types.html"
title="next chapter">Content types</a></p>
......@@ -132,7 +132,7 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<a href="content_types.html" title="Content types"
>next</a> |</li>
<li class="right" >
<a href="url_routing.html" title="URL Routing"
<a href="argument_parsing.html" title="Argument parsing"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......
......@@ -26,6 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Modular REST applications" href="modules.html" />
<link rel="prev" title="HTTP codes" href="http_codes.html" />
</head>
<body>
......@@ -35,6 +36,9 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
accesskey="P">previous</a> |</li>
......@@ -81,6 +85,9 @@
<h4>Previous topic</h4>
<p class="topless"><a href="http_codes.html"
title="previous chapter">HTTP codes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="modules.html"
title="next chapter">Modular REST applications</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/async.txt"
......@@ -109,6 +116,9 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
>next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
>previous</a> |</li>
......
......@@ -27,7 +27,7 @@
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Asynchronous Operations" href="async.html" />
<link rel="prev" title="Modular REST applications" href="modules.html" />
<link rel="prev" title="Filters" href="filters.html" />
</head>
<body>
<div class="related">
......@@ -40,7 +40,7 @@
<a href="async.html" title="Asynchronous Operations"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
<a href="filters.html" title="Filters"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......@@ -75,8 +75,8 @@
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="modules.html"
title="previous chapter">Modular REST applications</a></p>
<p class="topless"><a href="filters.html"
title="previous chapter">Filters</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="async.html"
title="next chapter">Asynchronous Operations</a></p>
......@@ -112,7 +112,7 @@
<a href="async.html" title="Asynchronous Operations"
>next</a> |</li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
<a href="filters.html" title="Filters"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......
......@@ -73,6 +73,14 @@
<li class="toctree-l2"><a class="reference internal" href="url_routing.html#routing-requests-by-incoming-content-type">Routing requests by incoming content type</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="argument_parsing.html">Argument parsing</a><ul>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#query-arguments">Query arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#form-encoded-arguments">Form encoded arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#json-document-arguments">JSON document arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#yaml-document-arguments">YAML document arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#xml-document-arguments">XML document arguments</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="arguments.html">Argument validation</a></li>
<li class="toctree-l1"><a class="reference internal" href="content_types.html">Content types</a><ul>
<li class="toctree-l2"><a class="reference internal" href="content_types.html#parsing-of-incoming-content">Parsing of incoming content</a></li>
......
......@@ -26,8 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="HTTP codes" href="http_codes.html" />
<link rel="prev" title="Argument validation" href="arguments.html" />
<link rel="prev" title="Asynchronous Operations" href="async.html" />
</head>
<body>
<div class="related">
......@@ -37,10 +36,7 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="async.html" title="Asynchronous Operations"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......@@ -184,11 +180,8 @@ and it takes care of routing the request to the appropriate class.</p>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="arguments.html"
title="previous chapter">Argument validation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="http_codes.html"
title="next chapter">HTTP codes</a></p>
<p class="topless"><a href="async.html"
title="previous chapter">Asynchronous Operations</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/modules.txt"
......@@ -218,10 +211,7 @@ and it takes care of routing the request to the appropriate class.</p>
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
>next</a> |</li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="async.html" title="Asynchronous Operations"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul>
......
Search.setIndex({objects:{},terms:{all:2,code:[0,1,3,4,5,7],partial:4,queri:[8,6],formencod:6,iresponsefilt:7,follow:7,rootid:6,depend:4,received_head:[7,3],readabl:5,specif:6,under:5,string:[4,3],veri:5,level:5,list:[6,7],small:2,pleas:6,enterpris:5,fortun:5,abil:5,design:5,pass:[7,3],val2:8,val1:8,phoneid:2,index:[],what:[0,5],savecustom:2,abl:1,current:[5,3],delet:[2,1],intarg:3,filterrespons:7,method:[8,5,1,3],can:[4,2,6,7,3],full:2,restservic:3,here:2,bodi:4,modular:[0,2],intercept:7,let:5,floatarg:3,address:2,path:[0,2,3],statecod:2,valu:7,convert:[4,0,3],convers:5,extrem:5,chang:7,via:[6,7,3],activ:7,modul:6,countrycod:2,api:5,select:8,regex:6,from:[6,5,2,1,3],would:[0,5,3],two:[2,7],handler:5,call:4,value2:6,value1:6,recommend:5,type:[4,0,7,3],more:5,desir:3,test_yaml:4,phone:2,indic:[],particular:5,known:5,customerid:2,content_typ:3,postvalidateschema:6,focu:5,del:2,thin:5,root:[8,7,3],def:[2,3,4,6,7,8],defer:[0,5,8],tap:3,give:5,accept:4,want:8,multipl:[],write:[5,2,3],how:5,instead:[4,0,5],simpl:3,product:[5,3],resourc:[2,7],befor:5,mesh:2,end:2,httpheader:3,tutori:5,seriou:5,element:2,callback:5,allow:[2,7],order:[2,7],dynam:[2,3],entiti:2,yaml:[4,5],jit:5,easier:5,them:[2,7,3],application_json:3,"return":[1,2,3,4,6,7],python:[4,0,5],nation:6,framework:[0,5],introduct:[0,5],trac:5,easili:3,wraparoundfilt:7,side:5,status:7,hard:5,expect:[4,0,3],paymentid:2,extract:[0,3],network:5,develop:5,crucial:5,content:[4,0,3],restresourc:[2,7,3],deleteal:2,test_content_app_json:3,integr:[4,6],standard:8,pleasant:5,base:[4,1,3],put:[4,2,1,3],org:6,care:[5,2],addressid:2,filter:[0,5,7],router:3,principl:5,interact:5,testschema:6,oper:[0,5,8],note:3,blown:2,grade:5,onc:5,lastnam:2,test_json:4,getallcustom:2,hook:3,miss:1,hood:5,differ:[2,3],addcustomheaderfilt:7,getcustomeraddress:2,customeraddress:2,top:[0,5],system:5,least:5,attach:4,conveni:3,schema:6,customeraddressrestservic:2,specifi:6,pars:[4,0,5],streetnumb:2,mostli:5,than:5,provid:5,structur:2,argument:[6,0,1,3],packag:6,have:2,"__main__":[2,3],need:7,inlinecallback:[0,8],test_return_content_by_accept:4,self:[2,3,4,6,7,8],especi:5,thorough:5,stringarg:3,take:[5,2],which:[5,2],noth:5,singl:2,simplifi:5,importantli:5,deletecustom:2,regular:2,why:[0,5],url:[4,0,2,1,3],request:[0,2,3,4,5,6,7,8],doe:[0,5],test_content_xml:3,runtim:5,wildcard:3,numericid:3,somewhat:5,show:3,text:4,xml:[4,5],just:[2,3,4,5,7,8],solut:5,plumb:5,should:5,busi:[5,2],meant:5,get:[1,2,3,5,7,8],pypi:5,requir:5,run_filter_app:7,change404to503filt:7,yield:8,"default":[4,1],common:[5,6],deleteallcustom:2,where:2,valid:[0,2,1,6],dump:4,see:6,mandatori:1,respons:[4,5,2,7],fail:1,extend:2,hopefulli:5,databas:5,behind:5,"import":[2,6,3],paramet:[2,7],approach:5,parent:2,both:7,howev:5,test_content_catch_al:3,etc:[2,3],instanc:7,logic:5,pdf:5,com:[5,3],simpli:5,header:7,guid:5,coupl:5,json:[4,5],much:5,basic:[5,3],search:[],ani:[5,1],notfoundexcept:2,dave:5,run_rest_app:2,child:2,"case":2,text_xml:3,tostr:4,servic:[5,2,7],"while":5,abov:2,error:1,fun:5,exist:[2,3],layer:5,twistedmatrix:[5,3],tabl:[],henc:5,toolkit:5,kwarg:[4,8,6,7,3],myapp:6,postvalidatecustom:6,incom:[4,0,7,3],twistd:3,decor:[0,3],allow_extra_field:6,perform:5,make:5,same:3,handl:5,html:[6,3],zope:7,document:[5,6,3],breakdown:[],http:[0,1,2,3,4,5,6,7,8],driven:[2,1],extern:5,typic:2,appropri:[2,1],eleg:5,well:5,coreport:3,exampl:[2,6,3],thi:[4,8,5,2,3],rout:[0,2,3,4,5,6,7,8],latest:6,test1:4,test2:4,firstnam:2,when:3,rest:[0,5,2],filterapp:7,test_content_yaml:3,yet:5,languag:5,web:[0,5,2,6,3],application_xml:3,except:5,getal:2,blog:5,add:[0,5,7],book:5,input:[5,7],app:[2,7,3],match:1,build:5,real:3,applic:[4,0,5,2,3],around:7,format:5,read:5,irequestfilt:7,howto:[5,3],piec:3,realiz:5,like:[5,2],success:1,filterrequest:7,test_get_resourc:3,either:[5,7],popular:6,output:7,page:[],childid:6,www:6,some:5,sampl:[2,3],server:[5,1],librari:5,kei:[],getcustom:2,micro:[0,5],peticola:5,outgo:7,unit:3,test_xml:4,complic:5,core:[5,3],object:[0,2,3,4,5,6],run:[2,7,3],power:5,payment:2,"enum":[6,3],usag:5,alreadyexistsexcept:2,async:[8,5],"__name__":[2,3],post:[4,6,2,1,3],actual:1,constructor:7,other:5,own:5,effici:5,"float":3,automat:[4,5,3],wrap:[2,7],your:3,invoiceid:2,val:4,support:[4,0,8,7,3],custom:[5,2,6,7],avail:6,reli:5,interfac:7,low:5,"function":[8,1,3],returnvalu:8,form:6,streetnam:2,inlin:5,"true":6,whether:4,page_id:5,caller:4,asynchron:[0,5,8],similar:5,featur:[0,5],creat:[5,2,1],"int":[6,3],customerrestservic:2,twist:[0,5,2,8,3],implement:[2,6,7],krondo:5,excel:5,elementtre:4,field:6,corepost:[0,1,2,3,4,5,6,7],test:3,you:[8,5,2,7,3],node:[0,5],matur:5,mediatyp:3,"class":[5,2,6,7,3],sql:5,text_yaml:3,understand:5,invoic:2},objtypes:{},titles:["CorePost","HTTP codes","Modular REST applications","URL Routing","Content types","Introduction","Argument validation","Filters","Asynchronous Operations"],objnames:{},filenames:["index","http_codes","modules","url_routing","content_types","intro","arguments","filters","async"]})
\ No newline at end of file
Search.setIndex({objects:{},terms:{all:[2,3],code:[0,1,4,5,6,8],partial:5,queri:[2,0,7,9],formencod:7,abil:6,follow:8,children:2,rootid:7,depend:5,received_head:[8,4],readabl:6,under:6,string:[5,4],veri:6,implement:[3,7,8],level:6,list:[7,8],getnam:2,small:3,corepost:[0,1,2,3,4,5,6,7,8],pleas:7,enterpris:6,fortun:6,iresponsefilt:8,direct:2,design:6,pass:[2,8,4],val2:9,val1:9,phoneid:3,index:[],what:[0,6],savecustom:3,abl:1,current:[6,4],delet:[3,1],intarg:4,filterrespons:8,method:[2,9,6,1,4],can:[2,3,4,5,7,8],full:3,usag:6,gener:2,here:3,bodi:5,modular:[0,3],intercept:8,let:[2,6],floatarg:4,address:3,path:[0,3,4],statecod:3,valu:8,convert:[5,0,4],convers:6,extrem:6,chang:8,via:[7,8,4],solut:6,modul:7,countrycod:3,api:6,select:9,regex:7,from:[1,2,3,4,6,7],would:[2,0,6,4],two:[3,8],handler:6,call:5,value2:7,value1:7,recommend:6,type:[2,0,5,8,4],more:6,desir:4,test_yaml:5,phone:3,indic:[],particular:6,known:6,effort:2,customerid:3,content_typ:4,postvalidateschema:7,focu:6,del:3,thin:6,root:[2,9,8,4],def:[2,3,4,5,7,8,9],defer:[0,6,9],tap:4,give:6,accept:5,want:9,multipl:[],write:[6,3,4],how:6,instead:[2,0,6,5],simpl:4,product:[6,4],resourc:[3,8],befor:6,mesh:3,end:3,httpheader:4,tutori:6,seriou:6,element:[2,3],test_return_content_by_accept:5,allow:[3,8],testschema:7,order:[3,8],vari:2,dynam:[3,4],entiti:3,yaml:[2,0,6,5],jit:6,main:2,easier:6,them:[2,3,8,4],"float":4,"return":[1,2,3,4,5,7,8],python:[5,0,6],nation:7,underneath:2,framework:[0,6],introduct:[0,6],name:2,trac:6,easili:4,wraparoundfilt:8,side:6,status:8,hard:6,expect:[2,0,5,4],paymentid:3,extract:[2,0,4],network:6,develop:6,crucial:6,content:[2,0,5,4],restresourc:[3,8,4],deleteal:3,test_content_app_json:4,integr:[5,7],standard:9,pleasant:6,base:[5,1,4],put:[2,5,3,1,4],org:7,care:[6,3],addressid:3,could:2,success:1,filter:[0,6,8],router:[2,4],principl:6,interact:6,first:2,oper:[0,6,9],note:4,blown:3,grade:6,onc:6,lastnam:3,test_json:5,getallcustom:3,hook:4,custom:[6,3,7,8],miss:1,hood:6,differ:[3,4],addcustomheaderfilt:8,dump:5,customeraddress:3,top:[0,6],system:6,least:6,attach:5,conveni:4,schema:7,customeraddressrestservic:3,specifi:7,pars:[2,0,6,5],streetnumb:3,somewhat:6,than:6,john:2,instanc:8,provid:6,structur:3,sai:2,argument:[2,0,1,7,4],packag:7,have:[2,3],tabl:[],need:8,inlinecallback:[0,9],callback:6,rout:[0,3,4,5,6,7,8,9],especi:6,thorough:6,stringarg:4,mix:2,without:2,build:6,which:[6,3],noth:6,singl:[2,3],simplifi:6,importantli:6,deletecustom:3,regular:3,why:[0,6],url:[5,0,3,1,4],request:[0,2,3,4,5,6,7,8,9],doe:[2,0,6],test_content_xml:4,runtim:6,wildcard:4,numericid:4,mostli:6,show:4,text:[2,5],xml:[2,0,6,5],onli:2,firstnam:3,activ:8,plumb:6,should:6,busi:[6,3],meant:6,get:[1,2,3,4,6,8,9],pypi:6,requir:[2,6],run_filter_app:8,filterapp:8,yield:9,whether:5,common:[6,7],deleteallcustom:3,where:3,respond:2,getcustomeraddress:3,see:[2,7],mandatori:1,respons:[2,5,6,3,8],fail:1,parent:3,hopefulli:6,databas:6,behind:6,"import":[3,7,4],paramet:[2,3,8],approach:6,attribut:2,extend:3,addit:2,both:8,last:2,howev:6,application_xml:4,etc:[3,4],text_xml:4,logic:6,pdf:6,com:[6,4],simpli:6,header:8,guid:6,coupl:6,json:[2,0,6,5],much:6,basic:[2,6,4],search:[],ani:[2,6,1],notfoundexcept:3,dave:6,run_rest_app:3,child:[2,3],those:2,"case":[2,3],look:2,tostr:5,servic:[6,3,8],"while":6,abov:[2,3],error:1,fun:6,layer:6,twistedmatrix:[6,4],"__main__":[3,4],henc:[2,6],toolkit:6,kwarg:[2,4,5,7,8,9],myapp:7,postvalidatecustom:7,incom:[5,0,8,4],twistd:4,decor:[0,4],allow_extra_field:7,perform:6,make:6,same:[2,4],handl:[2,6],html:[7,4],zope:8,document:[2,0,6,7,4],breakdown:[],http:[0,1,2,3,4,5,6,7,8,9],driven:[3,1],extern:6,typic:3,appropri:[3,1],eleg:6,well:[2,6],coreport:4,exampl:[2,3,7,4],thi:[2,3,4,5,6,9],self:[2,3,4,5,7,8,9],latest:7,test1:5,test2:5,just:[2,3,4,5,6,8,9],excel:6,rest:[2,0,6,3],change404to503filt:8,test_content_yaml:4,yet:6,languag:6,web:[0,6,3,7,4],test_content_catch_al:4,except:6,getal:3,blog:6,add:[0,6,8],book:6,input:[6,8],app:[3,8,4],match:1,take:[6,3],real:4,applic:[0,2,3,4,5,6],around:8,format:[2,6],read:6,irequestfilt:8,howto:[6,4],piec:4,realiz:6,like:[2,6,3],specif:7,filterrequest:8,test_get_resourc:4,either:[6,8],popular:7,output:[2,8],page:[],childid:7,www:7,some:6,back:2,sampl:[3,4],server:[6,1],librari:6,kei:[],getcustom:3,micro:[0,6],peticola:6,outgo:8,unit:4,test_xml:5,complic:6,localhost:2,core:[6,4],object:[0,3,4,5,6,7],run:[3,8,4],power:6,"enum":[7,4],restservic:4,alreadyexistsexcept:3,async:[9,6],"__name__":[3,4],post:[1,2,3,4,5,7],actual:1,constructor:8,other:6,own:6,effici:6,application_json:4,encod:[2,0],automat:[2,5,6,4],wrap:[3,8],your:4,invoiceid:3,val:5,support:[0,2,4,5,8,9],payment:3,avail:7,reli:6,interfac:8,low:6,"function":[9,1,4],returnvalu:9,form:[2,0,7],streetnam:3,inlin:6,"true":7,"default":[5,1],page_id:6,caller:5,asynchron:[0,6,9],below:2,similar:6,featur:[0,6],creat:[6,3,1],"int":[7,4],customerrestservic:3,twist:[0,6,3,9,4],exist:[3,4],curl:2,krondo:6,when:4,elementtre:5,field:7,valid:[2,0,3,1,7],test:4,you:[2,3,4,6,8,9],node:[2,0,6],matur:6,mediatyp:4,"class":[6,3,7,8,4],sql:6,text_yaml:4,understand:6,invoic:3},objtypes:{},titles:["CorePost","HTTP codes","Argument parsing","Modular REST applications","URL Routing","Content types","Introduction","Argument validation","Filters","Asynchronous Operations"],objnames:{},filenames:["index","http_codes","argument_parsing","modules","url_routing","content_types","intro","arguments","filters","async"]})
\ No newline at end of file
......@@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Argument validation" href="arguments.html" />
<link rel="next" title="Argument parsing" href="argument_parsing.html" />
<link rel="prev" title="Introduction" href="intro.html" />
</head>
<body>
......@@ -37,7 +37,7 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="argument_parsing.html" title="Argument parsing"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
......@@ -153,8 +153,8 @@ In a real production application you would use existing Twisted <em>twistd</em>
<p class="topless"><a href="intro.html"
title="previous chapter">Introduction</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="arguments.html"
title="next chapter">Argument validation</a></p>
<p class="topless"><a href="argument_parsing.html"
title="next chapter">Argument parsing</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/url_routing.txt"
......@@ -184,7 +184,7 @@ In a real production application you would use existing Twisted <em>twistd</em>
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="argument_parsing.html" title="Argument parsing"
>next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
......
......@@ -45,27 +45,40 @@
\newlabel{url_routing:path-argument-extraction}{{2.1.2}{4}{Path argument extraction\relax }{subsection.2.1.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3}}
\newlabel{url_routing:routing-requests-by-incoming-content-type}{{2.1.3}{4}{Routing requests by incoming content type\relax }{subsection.2.1.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Argument validation}{4}{section.2.2}}
\newlabel{arguments:argument-validation}{{2.2}{4}{Argument validation\relax }{section.2.2}{}}
\newlabel{arguments::doc}{{2.2}{4}{Argument validation\relax }{section.2.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Content types}{5}{section.2.3}}
\newlabel{content_types::doc}{{2.3}{5}{Content types\relax }{section.2.3}{}}
\newlabel{content_types:content-types}{{2.3}{5}{Content types\relax }{section.2.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.1}Parsing of incoming content}{5}{subsection.2.3.1}}
\newlabel{content_types:parsing-of-incoming-content}{{2.3.1}{5}{Parsing of incoming content\relax }{subsection.2.3.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.2}Converting Python objects to expected content type}{5}{subsection.2.3.2}}
\newlabel{content_types:converting-python-objects-to-expected-content-type}{{2.3.2}{5}{Converting Python objects to expected content type\relax }{subsection.2.3.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.4}Filters}{6}{section.2.4}}
\newlabel{filters::doc}{{2.4}{6}{Filters\relax }{section.2.4}{}}
\newlabel{filters:filters}{{2.4}{6}{Filters\relax }{section.2.4}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.5}HTTP codes}{7}{section.2.5}}
\newlabel{http_codes::doc}{{2.5}{7}{HTTP codes\relax }{section.2.5}{}}
\newlabel{http_codes:http-codes}{{2.5}{7}{HTTP codes\relax }{section.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.6}Asynchronous Operations}{7}{section.2.6}}
\newlabel{async:asynchronous-operations}{{2.6}{7}{Asynchronous Operations\relax }{section.2.6}{}}
\newlabel{async::doc}{{2.6}{7}{Asynchronous Operations\relax }{section.2.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6.1}@defer.inlineCallbacks support}{7}{subsection.2.6.1}}
\newlabel{async:defer-inlinecallbacks-support}{{2.6.1}{7}{@defer.inlineCallbacks support\relax }{subsection.2.6.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.7}Modular REST applications}{7}{section.2.7}}
\newlabel{modules::doc}{{2.7}{7}{Modular REST applications\relax }{section.2.7}{}}
\newlabel{modules:modular-rest-applications}{{2.7}{7}{Modular REST applications\relax }{section.2.7}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Argument parsing}{4}{section.2.2}}
\newlabel{argument_parsing::doc}{{2.2}{4}{Argument parsing\relax }{section.2.2}{}}
\newlabel{argument_parsing:argument-parsing}{{2.2}{4}{Argument parsing\relax }{section.2.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}Query arguments}{4}{subsection.2.2.1}}
\newlabel{argument_parsing:query-arguments}{{2.2.1}{4}{Query arguments\relax }{subsection.2.2.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}Form encoded arguments}{5}{subsection.2.2.2}}
\newlabel{argument_parsing:form-encoded-arguments}{{2.2.2}{5}{Form encoded arguments\relax }{subsection.2.2.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.3}JSON document arguments}{5}{subsection.2.2.3}}
\newlabel{argument_parsing:json-document-arguments}{{2.2.3}{5}{JSON document arguments\relax }{subsection.2.2.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.4}YAML document arguments}{5}{subsection.2.2.4}}
\newlabel{argument_parsing:yaml-document-arguments}{{2.2.4}{5}{YAML document arguments\relax }{subsection.2.2.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2.5}XML document arguments}{5}{subsection.2.2.5}}
\newlabel{argument_parsing:xml-document-arguments}{{2.2.5}{5}{XML document arguments\relax }{subsection.2.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}}
\newlabel{arguments:argument-validation}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\newlabel{arguments::doc}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}}
\newlabel{content_types::doc}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\newlabel{content_types:content-types}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.1}Parsing of incoming content}{6}{subsection.2.4.1}}
\newlabel{content_types:parsing-of-incoming-content}{{2.4.1}{6}{Parsing of incoming content\relax }{subsection.2.4.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.2}Converting Python objects to expected content type}{7}{subsection.2.4.2}}
\newlabel{content_types:converting-python-objects-to-expected-content-type}{{2.4.2}{7}{Converting Python objects to expected content type\relax }{subsection.2.4.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.5}Filters}{7}{section.2.5}}
\newlabel{filters::doc}{{2.5}{7}{Filters\relax }{section.2.5}{}}
\newlabel{filters:filters}{{2.5}{7}{Filters\relax }{section.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.6}HTTP codes}{8}{section.2.6}}
\newlabel{http_codes::doc}{{2.6}{8}{HTTP codes\relax }{section.2.6}{}}
\newlabel{http_codes:http-codes}{{2.6}{8}{HTTP codes\relax }{section.2.6}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.7}Asynchronous Operations}{8}{section.2.7}}
\newlabel{async:asynchronous-operations}{{2.7}{8}{Asynchronous Operations\relax }{section.2.7}{}}
\newlabel{async::doc}{{2.7}{8}{Asynchronous Operations\relax }{section.2.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.7.1}@defer.inlineCallbacks support}{8}{subsection.2.7.1}}
\newlabel{async:defer-inlinecallbacks-support}{{2.7.1}{8}{@defer.inlineCallbacks support\relax }{subsection.2.7.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.8}Modular REST applications}{9}{section.2.8}}
\newlabel{modules::doc}{{2.8}{9}{Modular REST applications\relax }{section.2.8}{}}
\newlabel{modules:modular-rest-applications}{{2.8}{9}{Modular REST applications\relax }{section.2.8}{}}
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.2.29) 8 MAR 2012 10:07
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.2.29) 19 MAR 2012 13:29
entering extended mode
%&-line parsing enabled.
**CorePost.tex
......@@ -903,34 +903,34 @@ LaTeX Font Info: Font shape `T1/pcr/m/it' in size <9> not available
[3
] [4] [5] [6] [7]
[8]
Underfull \vbox (badness 10000) detected at line 656
[8] [9]
Underfull \vbox (badness 10000) detected at line 750
[]
Underfull \vbox (badness 10000) detected at line 656
Underfull \vbox (badness 10000) detected at line 750
[]
[9] (./CorePost.ind) [10] (./CorePost.aux) )
[10] (./CorePost.ind) [11] (./CorePost.aux) )
Here is how much of TeX's memory you used:
7966 strings out of 493848
107801 string characters out of 1152823
197135 words of memory out of 3000000
11011 multiletter control sequences out of 15000+50000
7981 strings out of 493848
108170 string characters out of 1152823
197503 words of memory out of 3000000
11019 multiletter control sequences out of 15000+50000
55793 words of font info for 63 fonts, out of 3000000 for 9000
715 hyphenation exceptions out of 8191
45i,12n,45p,426b,381s stack positions out of 5000i,500n,10000p,200000b,50000s
{/usr/share/texmf-texlive/fonts/enc
/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb8a.pfb
></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texmf
-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fonts/ty
pe1/urw/helvetic/uhvb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/helvetic/
uhvbo8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmb8a.pfb></usr/sh
are/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texlive/fo
nts/type1/urw/times/utmri8a.pfb>
Output written on CorePost.pdf (14 pages, 143233 bytes).
{/usr/share/texmf-texlive/fonts/en
c/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb8a.pf
b></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texm
f-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fonts/t
ype1/urw/helvetic/uhvb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/helvetic
/uhvbo8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmb8a.pfb></usr/s
hare/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texlive/f
onts/type1/urw/times/utmri8a.pfb>
Output written on CorePost.pdf (15 pages, 149329 bytes).
PDF statistics:
175 PDF objects out of 1000 (max. 8388607)
35 named destinations out of 1000 (max. 500000)
81 words of extra memory for PDF output out of 10000 (max. 10000000)
192 PDF objects out of 1000 (max. 8388607)
42 named destinations out of 1000 (max. 500000)
89 words of extra memory for PDF output out of 10000 (max. 10000000)
......@@ -2,9 +2,10 @@
\BOOKMARK [1][-]{section.1.1}{Introduction}{chapter.1}
\BOOKMARK [0][-]{chapter.2}{Features}{}
\BOOKMARK [1][-]{section.2.1}{URL Routing}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Argument validation}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Content types}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Filters}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{HTTP codes}{chapter.2}
\BOOKMARK [1][-]{section.2.6}{Asynchronous Operations}{chapter.2}
\BOOKMARK [1][-]{section.2.7}{Modular REST applications}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Argument parsing}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Argument validation}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Content types}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Filters}{chapter.2}
\BOOKMARK [1][-]{section.2.6}{HTTP codes}{chapter.2}
\BOOKMARK [1][-]{section.2.7}{Asynchronous Operations}{chapter.2}
\BOOKMARK [1][-]{section.2.8}{Modular REST applications}{chapter.2}
......@@ -13,7 +13,7 @@
\title{CorePost Documentation}
\date{March 08, 2012}
\date{March 19, 2012}
\release{0.0.14}
\author{Jacek Furmankiewicz}
\newcommand{\sphinxlogo}{}
......@@ -298,6 +298,100 @@ Based on the incoming content type in POST/PUT requests, the \emph{same} URL can
\end{Verbatim}
\section{Argument parsing}
\label{argument_parsing::doc}\label{argument_parsing:argument-parsing}
CorePost can automatically parse query arguments, form arguments, as well as basic JSON, YAML and XML documents
and extract those as direct arguments to a REST router method.
Let's say we have a basic method that responds to GET, POST and PUT requests.
It expects a first name and last name and outputs them back in the response:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@router}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/name}\PYG{l+s}{"}\PYG{p}{,}\PYG{p}{(}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{POST}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{PUT}\PYG{p}{)}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{getName}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{first}\PYG{p}{,}\PYG{n}{last}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{l+s}{"}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{ }\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{"} \PYG{o}{\PYGZpc{}} \PYG{p}{(}\PYG{n}{first}\PYG{p}{,} \PYG{n}{last}\PYG{p}{)}
\end{Verbatim}
\subsection{Query arguments}
\label{argument_parsing:query-arguments}
For GET requests, the query arguments will be automatically parsed, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
curl http://127.0.0.1/name?first=John\&last=Doe
\end{Verbatim}
\subsection{Form encoded arguments}
\label{argument_parsing:form-encoded-arguments}
For POST/PUT requests, any form-encoded arguments will be automatically parsed, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
curl -X POST http://localhost/name -d "first=John\&last=Doe"
\end{Verbatim}
\subsection{JSON document arguments}
\label{argument_parsing:json-document-arguments}
For the same method, you could just post a JSON document instead that looks like this:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{first}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{John}\PYG{l+s}{"}\PYG{p}{,}\PYG{l+s}{"}\PYG{l+s}{last}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{Doe}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}
\end{Verbatim}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the \emph{`application/json'} content type to be passed.
\subsection{YAML document arguments}
\label{argument_parsing:yaml-document-arguments}
For the same method, you could just post a YAML document that looks like this:
\begin{Verbatim}[commandchars=\\\{\}]
first:John
last:Doe
\end{Verbatim}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the \emph{`text/yaml'} content type to be passed.
\subsection{XML document arguments}
\label{argument_parsing:xml-document-arguments}
XML documents are supported as well. In that case, CorePost will first parse all the attributes on the root node
and then all of the children underneath the main root node.
Hence all of the XML formats below are valid and would generate the same parameters to a method.
Attributes only:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root first="John" last="Doe"/\textgreater{}
\end{Verbatim}
Mix of attributes and child nodes:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root first="John"\textgreater{}
\textless{}last\textgreater{}Doe\textless{}/last\textgreater{}
\textless{}/root\textgreater{}
\end{Verbatim}
Child nodes only:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root\textgreater{}
\textless{}first\textgreater{}John\textless{}/first\textgreater{}
\textless{}last\textgreater{}Doe\textless{}/last\textgreater{}
\textless{}/root\textgreater{}
\end{Verbatim}
Requires the \emph{`text/xml'} OR \emph{`application/xml'} content type to be passed.
As you can see from the examples above, a single CorePost router method can handle all these varied forms of argument parsing
for you without any additional effort.
\section{Argument validation}
\label{arguments:argument-validation}\label{arguments::doc}
CorePost integrates the popular `formencode' package to implement form and query argument validation.
......
......@@ -10,12 +10,18 @@
\contentsline {subsection}{\numberline {2.1.1}@route decorator}{3}{subsection.2.1.1}
\contentsline {subsection}{\numberline {2.1.2}Path argument extraction}{4}{subsection.2.1.2}
\contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3}
\contentsline {section}{\numberline {2.2}Argument validation}{4}{section.2.2}
\contentsline {section}{\numberline {2.3}Content types}{5}{section.2.3}
\contentsline {subsection}{\numberline {2.3.1}Parsing of incoming content}{5}{subsection.2.3.1}
\contentsline {subsection}{\numberline {2.3.2}Converting Python objects to expected content type}{5}{subsection.2.3.2}
\contentsline {section}{\numberline {2.4}Filters}{6}{section.2.4}
\contentsline {section}{\numberline {2.5}HTTP codes}{7}{section.2.5}
\contentsline {section}{\numberline {2.6}Asynchronous Operations}{7}{section.2.6}
\contentsline {subsection}{\numberline {2.6.1}@defer.inlineCallbacks support}{7}{subsection.2.6.1}
\contentsline {section}{\numberline {2.7}Modular REST applications}{7}{section.2.7}
\contentsline {section}{\numberline {2.2}Argument parsing}{4}{section.2.2}
\contentsline {subsection}{\numberline {2.2.1}Query arguments}{4}{subsection.2.2.1}
\contentsline {subsection}{\numberline {2.2.2}Form encoded arguments}{5}{subsection.2.2.2}
\contentsline {subsection}{\numberline {2.2.3}JSON document arguments}{5}{subsection.2.2.3}
\contentsline {subsection}{\numberline {2.2.4}YAML document arguments}{5}{subsection.2.2.4}
\contentsline {subsection}{\numberline {2.2.5}XML document arguments}{5}{subsection.2.2.5}
\contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}
\contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}
\contentsline {subsection}{\numberline {2.4.1}Parsing of incoming content}{6}{subsection.2.4.1}
\contentsline {subsection}{\numberline {2.4.2}Converting Python objects to expected content type}{7}{subsection.2.4.2}
\contentsline {section}{\numberline {2.5}Filters}{7}{section.2.5}
\contentsline {section}{\numberline {2.6}HTTP codes}{8}{section.2.6}
\contentsline {section}{\numberline {2.7}Asynchronous Operations}{8}{section.2.7}
\contentsline {subsection}{\numberline {2.7.1}@defer.inlineCallbacks support}{8}{subsection.2.7.1}
\contentsline {section}{\numberline {2.8}Modular REST applications}{9}{section.2.8}
Argument parsing
===================
CorePost can automatically parse query arguments, form arguments, as well as basic JSON, YAML and XML documents
and extract those as direct arguments to a REST router method.
Let's say we have a basic method that responds to GET, POST and PUT requests.
It expects a first name and last name and outputs them back in the response::
@router("/name",(Http.GET,Http.POST,Http.PUT))
def getName(self,request,first,last,**kwargs):
return "%s %s" % (first, last)
Query arguments
---------------
For GET requests, the query arguments will be automatically parsed, e.g.::
curl http://127.0.0.1/name?first=John&last=Doe
Form encoded arguments
----------------------
For POST/PUT requests, any form-encoded arguments will be automatically parsed, e.g.::
curl -X POST http://localhost/name -d "first=John&last=Doe"
JSON document arguments
-----------------------
For the same method, you could just post a JSON document instead that looks like this::
{"first":"John","last":"Doe"}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the *'application/json'* content type to be passed.
YAML document arguments
-----------------------
For the same method, you could just post a YAML document that looks like this::
first:John
last:Doe
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the *'text/yaml'* content type to be passed.
XML document arguments
----------------------
XML documents are supported as well. In that case, CorePost will first parse all the attributes on the root node
and then all of the children underneath the main root node.
Hence all of the XML formats below are valid and would generate the same parameters to a method.
Attributes only::
<root first="John" last="Doe"/>
Mix of attributes and child nodes::
<root first="John">
<last>Doe</last>
</root>
Child nodes only::
<root>
<first>John</first>
<last>Doe</last>
</root>
Requires the *'text/xml'* OR *'application/xml'* content type to be passed.
As you can see from the examples above, a single CorePost router method can handle all these varied forms of argument parsing
for you without any additional effort.
......@@ -16,9 +16,11 @@ Features
:maxdepth: 4
url_routing
argument_parsing
arguments
content_types
filters
http_codes
async
modules
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment