Re: RESTful Toggle
"'Simpson, Robby (GE Energy Management)' [email protected] [rest-discuss]" <[email protected]> Wed, 9 Jul 2014 14:52:44 +0000
| Newsgroups | gmane.comp.web.services.rest |
|---|---|
| Message-ID | <CFE2CC09.376C6%[email protected]> |
--f2DOJ00uXKy1WvMO0FgTq6lkaJSm2Dy6l4Mr-2f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable All, Thanks so much for the rapid replies! A few comments / requests for = clarifications: Many have mentioned using conditional PUTs. This will cer= tainly solve the race conditions that I was worried about. However, it wil= l require some network chattiness (a GET to retrieve the current representa= tion and ETag / Last-Modified, followed by a PUT with the appropriate heade= r) which may require multiple round-trips should the state change between t= he GET and PUT. Any thoughts on ways to avoid this chattiness and still ma= intain the RESTful principles? In a perfect world, this could be accomplis= hed with a single request, as the client does not really care what the curr= ent state is, the client merely wishes to toggle the state (e.g., a light s= witch that is simply a button). ----- Others have mentioned the use of a = POST. To better understand the POST semantics, I've created an example bel= ow: /switch --- (a GET will return the current state: "On" or "Off" ;= a PUT will modify the current state: "On" or "Off) I'm guessing that the = POST would be to a resource such as /switch/toggle However, I'm wondering = if this violates RESTful principles and actually creates more of an RPC-lik= e style. Or perhaps I'm just overthinking.. It is unclear to me what the = body of the POST to /switch/toggle would contain as well as what should hap= pen if a GET or a PUT were performed. Thanks, Robby From: Keith P Hassen = <[email protected]<mailto:[email protected]>> Date: Wednesday, Ju= ly 9, 2014 at 9:06 AM To: Charles Simpson <[email protected]<mailto:Robb= [email protected]>> Cc: "[email protected]<mailto:rest-discuss@ya= hoogroups.com>" <[email protected]<mailto:rest-discuss@yahoogrou= ps.com>> Subject: Re: [rest-discuss] RESTful Toggle You could implement a = POST operation that simply flips the state, whatever it is. If you impleme= nt PUT, the request should be idempotent but it's unclear if that's what yo= u intend here. Protecting against the kind of race conditions you mention = is usually performed with conditional requests (If-Match, If-None-Match, et= c). K On Tue, Jul 8, 2014 at 5:28 PM, 'Simpson, Robby (GE Energy Manage= ment)' [email protected]<mailto:[email protected]> [rest-discuss] <re= [email protected]<mailto:rest-discuss-noreply@yahoogroups.= com>> wrote: Hi, I've been scratching my head over this one for a while = and am hoping I can get some help. Imagine a light switch with one simple = resource: /state , where state can be "On" or "Off." One can PUT to /state= , changing /state to either "On" or "Off." Similarly, a GET to /state will= tell you if the light is currently "On" or "Off." Where I'm struggling is= with a safe "Toggle" mechanism. That is, if /state is "On", change it to "= Off" and vice versa. I understand that one solution would be to simply per= form a GET on /state and then PUT the opposite. However, I am concerned wit= h both the overhead and latency this entails as well as the potential for a= race condition (what if /state changes between the GET and the PUT?). Any= solution I've looked at thus far seems to violate RESTful principles, part= icularly regarding idempotency. In short, can one safely toggle? Any sugge= stions? Thanks, Robby --f2DOJ00uXKy1WvMO0FgTq6lkaJSm2Dy6l4Mr-2f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> </head> <body style="background-color: #fff;"> <span style="display:none"> </span> <!--~-|**|PrettyHtmlStartT|**|-~--> <div id="ygrp-mlmsg" style="position:relative;"> <div id="ygrp-msg" style="z-index: 1;"> <!--~-|**|PrettyHtmlEndT|**|-~--> <div id="ygrp-text" > <p>All,<br> <br> Thanks so much for the rapid replies! A few comments / requests for clarifications:<br> <br> Many have mentioned using conditional PUTs. This will certainly solve the race conditions that I was worried about. However, it will require some network chattiness (a GET to retrieve the current representation and ETag / Last-Modified, followed by a PUT with the appropriate header) which may require multiple round-trips should the state change between the GET and PUT. Any thoughts on ways to avoid this chattiness and still maintain the RESTful principles? In a perfect world, this could be accomplished with a single request, as the client does not really care what the current state is, the client merely wishes to toggle the state (e.g., a light switch that is simply a button).<br> <br> -----<br> <br> Others have mentioned the use of a POST. To better understand the POST semantics, I've created an example below:<br> <br> /switch --- (a GET will return the current state: "On" or "Off" ; a PUT will modify the current state: "On" or "Off)<br> <br> I'm guessing that the POST would be to a resource such as /switch/toggle<br> <br> However, I'm wondering if this violates RESTful principles and actually creates more of an RPC-like style. Or perhaps I'm just overthinking..<br> <br> It is unclear to me what the body of the POST to /switch/toggle would contain as well as what should happen if a GET or a PUT were performed.<br> <br> Thanks,<br> Robby<br> <br> From: Keith P Hassen <[email protected]<mailto:[email protected]>><br> Date: Wednesday, July 9, 2014 at 9:06 AM<br> To: Charles Simpson <[email protected]<mailto:[email protected]>><br> Cc: "[email protected]<mailto:[email protected]>" <[email protected]<mailto:[email protected]>><br> Subject: Re: [rest-discuss] RESTful Toggle<br> <br> You could implement a POST operation that simply flips the state, whatever it is. If you implement PUT, the request should be idempotent but it's unclear if that's what you intend here. Protecting against the kind of race conditions you mention is usually performed with conditional requests (If-Match, If-None-Match, etc).<br> <br> K<br> <br> On Tue, Jul 8, 2014 at 5:28 PM, 'Simpson, Robby (GE Energy Management)' [email protected]<mailto:[email protected]> [rest-discuss] <[email protected]<mailto:[email protected]>> wrote:<br> <br> Hi,<br> <br> I've been scratching my head over this one for a while and am hoping I can<br> get some help.<br> <br> Imagine a light switch with one simple resource: /state , where state can<br> be "On" or "Off."<br> <br> One can PUT to /state , changing /state to either "On" or "Off."<br> Similarly, a GET to /state will tell you if the light is currently "On" or<br> "Off."<br> <br> Where I'm struggling is with a safe "Toggle" mechanism. That is, if<br> /state is "On", change it to "Off" and vice versa.<br> <br> I understand that one solution would be to simply perform a GET on /state<br> and then PUT the opposite. However, I am concerned with both the overhead<br> and latency this entails as well as the potential for a race condition<br> (what if /state changes between the GET and the PUT?).<br> <br> Any solution I've looked at thus far seems to violate RESTful principles,<br> particularly regarding idempotency. In short, can one safely toggle?<br> <br> Any suggestions?<br> <br> Thanks,<br> Robby<br> <br> </p> </div> <!--~-|**|PrettyHtmlStart|**|-~--> <div style="color: #fff; height: 0;">__._,_.___</div> <div style="clear:both"> </div> <div id="fromDMARC" style="margin-top: 10px;"> <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;"> Posted by: "Simpson, Robby (GE Energy Management)" <[email protected]> <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;"> </div> <div style="clear:both"> </div> <table cellspacing=4px style="margin-top: 10px; margin-bottom: 10px; color: #2D50FD;"> <tbody> <tr> <td style="font-size: 12px; font-family: arial; font-weight: bold; padding: 7px 5px 5px;" > <a style="text-decoration: none; color: #2D50FD" href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/messages/19666;_ylc=X3oDMTJxZGgyZzRvBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NjY2BHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTQwNDkxNzk3NA--?act=reply&messageNum=19666">Reply via web post</a> </td> <td>•</td> <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;" > <a href="mailto:[email protected]?subject=Re%3A%20%5Brest-discuss%5D%20RESTful%20Toggle" style="text-decoration: none; color: #2D50FD;"> Reply to sender </a> </td> <td>•</td> <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;"> <a href="mailto:[email protected]?subject=Re%3A%20%5Brest-discuss%5D%20RESTful%20Toggle" style="text-decoration: none; color: #2D50FD"> Reply to group </a> </td> <td>•</td> <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;" > <a href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/newtopic;_ylc=X3oDMTJlZHI4dGxlBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTQwNDkxNzk3NA--" style="text-decoration: none; color: #2D50FD">Start a New Topic</a> </td> <td>•</td> <td style="font-size: 12px; font-family: arial; padding: 7px 5px 5px;color: #2D50FD;" > <a href="https://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/19657;_ylc=X3oDMTM2cHVjN2MwBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NjY2BHNlYwNmdHIEc2xrA3Z0cGMEc3RpbWUDMTQwNDkxNzk3NAR0cGNJZAMxOTY1Nw--" style="text-decoration: none; color: #2D50FD;">Messages in this topic</a> (10) </td> </tr> </tbody> </table> <!------- Start Nav Bar ------> <!-- |**|begin egp html banner|**| --> <div id="ygrp-vital" style="background-color: #f2f2f2; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;"> <span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; "><a href="https://groups.yahoo.com/neo/groups/rest-discuss/info;_ylc=X3oDMTJlbWoybG9xBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQwNDkxNzk3NA--" style="text-decoration: none;">Visit Your Group</a></span> <ul style="list-style-type: none; margin: 0; padding: 0; display: inline;"> <li style="border-right: 1px solid #000; font-weight: 700; display: inline; padding: 0 5px; margin-left: 0;"> <span class="cat"><a href="https://groups.yahoo.com/neo/groups/rest-discuss/members/all;_ylc=X3oDMTJmZzIzZDIyBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0MDQ5MTc5NzQ-" style="text-decoration: none;">New Members</a></span> <span class="ct" style="color: #ff7900;">2</span> </li> </ul> </div> <div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;"> <a href="https://groups.yahoo.com/neo;_ylc=X3oDMTJkb2NpNHN2BF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxNDA0OTE3OTc0" style="float: left;"><img src="http://l.yimg.com/ru/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a> <div style="color: #747575; float: right;"> • <a href="https://info.yahoo.com/privacy/us/yahoo/groups/details.html" style="text-decoration: none;">Privacy</a> • <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> • <a href="https://info.yahoo.com/legal/us/yahoo/utos/terms/" style="text-decoration: none;">Terms of Use</a> </div> </div> <br> <!-- |**|end egp html banner|**| --> </div> <!-- ygrp-msg --> <!-- Sponsor --> <!-- |**|begin egp html banner|**| --> <div id="ygrp-sponsor" style="width:160px; float:right; clear:none; margin:0 0 25px 0; background: #fff;"> <!-- Start Recommendations --> <div id="ygrp-reco"> </div> <!-- End Recommendations --> </div> <!-- |**|end egp html banner|**| --> <div style="clear:both; color: #FFF; font-size:1px;">.</div> </div> <img src="http://geo.yahoo.com/serv?s=97359714/grpId=4319255/grpspId=1705701014/msgId=19666/stime=1404917974" width="1" height="1"> <br> <img src="http://y.analytics.yahoo.com/fpc.pl?ywarid=515FB27823A7407E&a=10001310322279&js=no&resp=img" width="1" height="1"> <div style="color: #fff; height: 0;">__,_._,___</div> <!--~-|**|PrettyHtmlEnd|**|-~--> </body> <!--~-|**|PrettyHtmlStart|**|-~--> <head> <style type="text/css"> <!-- #ygrp-mkp { border: 1px solid #d8d8d8; font-family: Arial; margin: 10px 0; padding: 0 10px; } #ygrp-mkp hr { border: 1px solid #d8d8d8; } #ygrp-mkp #hd { color: #628c2a; font-size: 85%; font-weight: 700; line-height: 122%; margin: 10px 0; } #ygrp-mkp #ads { margin-bottom: 10px; } #ygrp-mkp .ad { padding: 0 0; } #ygrp-mkp .ad p { margin: 0; } #ygrp-mkp .ad a { color: #0000ff; text-decoration: none; } #ygrp-sponsor #ygrp-lc { font-family: Arial; } #ygrp-sponsor #ygrp-lc #hd { margin: 10px 0px; font-weight: 700; font-size: 78%; line-height: 122%; } #ygrp-sponsor #ygrp-lc .ad { margin-bottom: 10px; padding: 0 0; } #actions { font-family: Verdana; font-size: 11px; padding: 10px 0; } #activity { background-color: #e0ecee; float: left; font-family: Verdana; font-size: 10px; padding: 10px; } #activity span { font-weight: 700; } #activity span:first-child { text-transform: uppercase; } #activity span a { color: #5085b6; text-decoration: none; } #activity span span { color: #ff7900; } #activity span .underline { text-decoration: underline; } .attach { clear: both; display: table; font-family: Arial; font-size: 12px; padding: 10px 0; width: 400px; } .attach div a { text-decoration: none; } .attach img { border: none; padding-right: 5px; } .attach label { display: block; margin-bottom: 5px; } .attach label a { text-decoration: none; } blockquote { margin: 0 0 0 4px; } .bold { font-family: Arial; font-size: 13px; font-weight: 700; } .bold a { text-decoration: none; } dd.last p a { font-family: Verdana; font-weight: 700; } dd.last p span { margin-right: 10px; font-family: Verdana; font-weight: 700; } dd.last p span.yshortcuts { margin-right: 0; } div.attach-table div div a { text-decoration: none; } div.attach-table { width: 400px; } div.file-title a, div.file-title a:active, div.file-title a:hover, div.file-title a:visited { text-decoration: none; } div.photo-title a, div.photo-title a:active, div.photo-title a:hover, div.photo-title a:visited { text-decoration: none; } div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts { font-family: Verdana; font-size: 10px; font-weight: normal; } .green { color: #628c2a; } .MsoNormal { margin: 0 0 0 0; } o { font-size: 0; } #photos div { float: left; width: 72px; } #photos div div { border: 1px solid #666666; height: 62px; overflow: hidden; width: 62px; } #photos div label { color: #666666; font-size: 10px; overflow: hidden; text-align: center; white-space: nowrap; width: 64px; } #reco-category { font-size: 77%; } #reco-desc { font-size: 77%; } .replbq { margin: 4px; } #ygrp-actbar div a:first-child { /* border-right: 0px solid #000;*/ margin-right: 2px; padding-right: 5px; } #ygrp-mlmsg { font-size: 13px; font-family: Arial, helvetica,clean, sans-serif; *font-size: small; *font: x-small; } #ygrp-mlmsg table { font-size: inherit; font: 100%; } #ygrp-mlmsg select, input, textarea { font: 99% Arial, Helvetica, clean, sans-serif; } #ygrp-mlmsg pre, code { font:115% monospace; *font-size:100%; } #ygrp-mlmsg * { line-height: 1.22em; } #ygrp-mlmsg #logo { padding-bottom: 10px; } #ygrp-msg p a { font-family: Verdana; } #ygrp-msg p#attach-count span { color: #1E66AE; font-weight: 700; } #ygrp-reco #reco-head { color: #ff7900; font-weight: 700; } #ygrp-reco { margin-bottom: 20px; padding: 0px; } #ygrp-sponsor #ov li a { font-size: 130%; text-decoration: none; } #ygrp-sponsor #ov li { font-size: 77%; list-style-type: square; padding: 6px 0; } #ygrp-sponsor #ov ul { margin: 0; padding: 0 0 0 8px; } #ygrp-text { font-family: Georgia; } #ygrp-text p { margin: 0 0 1em 0; } #ygrp-text tt { font-size: 120%; } #ygrp-vital ul li:last-child { border-right: none !important; } --> </style> </head> <!--~-|**|PrettyHtmlEnd|**|-~--> </html> <!-- end group email --> --f2DOJ00uXKy1WvMO0FgTq6lkaJSm2Dy6l4Mr-2f--