Ok, I have thought about it. ;-) For each resource there are a number of REST paths that are created/needed/whatever. Each path has a route name and two parameters (method and id).
GET /orders orders :method = get (default) GET /orders/new orders_new POST /orders orders :method = post GET /orders/1 order :method = get (default) , :id = 1 GET /orders/1/edit order_edit :method = get, :id = 1 PUT /orders/1 order :method = put , :id = 1 DELETE /orders/1 order :method = delete, :id =1 In today's world I usually create a small "Routes" section at the top of the page and use <s:url id=xxx/> to create my urls that I will reference later in the page. The new tags would have some new parameters: * route: the route name based on the convention above * method: the http method to use (default: GET) * id: the id to append to particular routes (default: %{id}) <s:url route="orders_path"/> = GET /orders <s:url route="order_path"/> = GET /orders/%{id} What about PUT, DELETE and POST. Well when you selecting a named route for a link for instance and you are using something other than GET, then the generated link should actually create a form with a hidden _method field and post to the server (with id if appropriate). It should also be smart enough to know that when I am in a s:form and using route="xxx" and method = "put" that i need to add a hidden field to my form. <s:form route="order_path" method="put"/> = <form action="/orders/%{id}" method="POST"><input type="hidden" name="_method" value="PUT"/></form> s:url is probably not as useful because what I really want to do is either generate a <a/> tag or a <form/> and a <a/> tag that submits the form. The current a tag has a lot of "stuff" and so I am not sure if this is a new <s:restA/> or an adaptation of the existing A tag. I think the idea of separating the s:url and s:a because of parameters is not a great idea. Instead we should use an OGNL hash for any "extra" parameters you want in the link. Obviously for a form you just include the fields.... Here is a use case.... I want to iterate over orders and generate an "Update Status to Complete link" as a column in the table. <s:iterator value="model"/> <tr> .... <td><s:a route="order_path" method="put" id="id" params="#{'status':'complete'}>Complete</s:a></td> </tr> </s:iterator/> creates <td><form action="/orders/[id for model in loop]" method="post" id="something generated i can reuse in my link"><input type="hidden" name="_method" value="PUT"/><input type="hidden" name="status" value="complete"/></form><a href=javascript:document.forms['reused id'].submit();return false>Complete</a></td> .... or something better ;-) Some key points: * s:a and s:form are the priority but s:url and s:action should have the same behavior if they are going to still be around. * Any method other than GET generates a form (if not already a form) and posts * Tags parse the route name for one of the four names (models, model, models_new, model_edit) to figure out the base url. This is where convention really makes a difference because if you misspell your route name then it will break. (Of course you could always create the urls by hand like we do today....but that is the benefit of convention) * the tag parameters should evaluate so you can insert the id of something in the ValueStack or you can even build your route name based on the valueStack. (This gets to some of the struts2 syntax "sugar") ** route: "orders" = string orders "%{orders}" orders value on the stack. Yes/No? ** id: "id" = id value on the stack "%{'id'}" string id. Yes/No? ** method: "get" string get "%{get}" get value on the stack. Yes/No? * Using GET with a params hash will just append to the querystring so: <s:a route="order_path" id="id" params="#{'status':'complete'}/> creates /orders/%{id}?status=complete. * Custom actions are just appended to the route name. So if you had an action called deleteConfirm then you would have the route <s:a route="order_deleteConfirm"/> which is /orders/%{id}/deleteConfirm and <s:a route="orders_deleteConfirm"/> which is /orders?action=deleteConfirm. (the second url is funny because I don't think the ActionMapper can tell the difference between /orders/1 and orders/deleteConfirm and not think that deleteConfirm is an order id.) That is a start and I think its a pretty straight forward implementation. I am sure it can be refined and improved. I am not so sure about how to setup "evaluation" of tag parameters against the stack. This whole brain dump spawned another idea, separate from REST but related, Named Routes. Named Routes are configured in struts.xml and allow the developer to create custom urls. So in struts.xml I enter: <route name="secret_back_door" path="/secret/:key/:function" controller="admin" action="index" methods="GET"/> This should do a few things: 1. When it sees /secret/DE2134123DF123412312321/report it will call the index() method of the class AdminController and pass in key=DE2134123DF123412312321,function=report. 2. When I write <s:a route="secret_back_door" params="#{'key':'DE2134123DF123412312321','function':'report'}/> I get /secret/DE2134123DF123412312321/report. 3. If I try to use PUT, POST or DELETE for this named route its an error. If I wanted it to respond to more methods then I would add them in struts.xml methods="GET,POST" I am not as sure how to implement this, but I know how to use it in my head. ;-) dusty wrote: > > That is a very good question Don. I am going to have to actually think > about that if you don't mind... > > > Don Brown-2 wrote: >> >> On Sun, Jun 22, 2008 at 1:46 PM, dusty <[EMAIL PROTECTED]> wrote: >>> In my UI I have things like <s:url/> and <s:form/> and <s:action/> that >>> are >>> going to need to address resources. The routing system should make it >>> easy >>> for me to both recognize incoming urls and to define rules for outbound >>> url >>> html. Is the answer to create a custom tag library for <s:form/> that >>> hides >>> the url details? or use a <s:url/> and reference that in <s:form>. I >>> think >>> making the action param evaluate is moving in the wrong direction, >>> making it >>> even more forced. A centralized REST routing system would be better so >>> that >>> we can just reference it when we need to talk to resources. >> >> What would this routing system look like? Ignore how Struts is >> designed today - how would you want such a system to work? How would >> you configure it? >> >> Don >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> > > -- View this message in context: http://www.nabble.com/RESTful-form-tags-tp18040304p18295144.html Sent from the Struts - Dev mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]