Re: RESTful Toggle
"Keith P Hassen [email protected] [rest-discuss]" <[email protected]> Wed, 9 Jul 2014 09:06:08 -0400
| Newsgroups | gmane.comp.web.services.rest |
|---|---|
| Message-ID | <CAP=4TEiH4oY_HOkG0jFeEHf52MycPFm53kXeXROv=qtRnGXg4g@mail.gmail.com> |
--001a11c13b601d548604fdc25f8a Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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). K On Tue, Jul 8, 2014 at 5:28 PM, 'Simpson, Robby (GE Energy Management)' [email protected] [rest-discuss] <[email protected]> wrote: > > > Hi, > > I've been scratching my head over this one for a while and am hoping I ca= n > 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" o= r > "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 perform a GET on /state > and then PUT the opposite. However, I am concerned with 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, > particularly regarding idempotency. In short, can one safely toggle? > > Any suggestions? > > Thanks, > Robby > >=20=20 > --001a11c13b601d548604fdc25f8a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/htm= l4/strict.dtd"> <html> <head> </head> =20 <body style=3D"background-color: #fff;"> <span style=3D"display:none"> </span> <!--~-|**|PrettyHtmlStartT|**|-~--> <div id=3D"ygrp-mlmsg" style=3D"position:relative;"> <div id=3D"ygrp-msg" style=3D"z-index: 1;"> <!--~-|**|PrettyHtmlEndT|**|-~--> <div id=3D"ygrp-text" > =20=20=20=20=20=20 =20=20=20=20=20=20 <p><div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family= :trebuchet ms,sans-serif;font-size:small;color:rgb(51,51,51);">You could im= plement a POST operation that simply flips the state, whatever it is.=C2=A0= If you implement PUT, the request should be idempotent but it's unclea= r if that's what you intend here.=C2=A0 Protecting against the kind of = race conditions you mention is usually performed with conditional requests = (If-Match, If-None-Match, etc).<br> <br></div><div class=3D"gmail_default" style=3D"font-family:trebuchet ms,sa= ns-serif;font-size:small;color:rgb(51,51,51);">K<br><br></div></div><div cl= ass=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Tue, Jul 8, 2014 = at 5:28 PM, 'Simpson, Robby (GE Energy Management)' <a href=3D"mail= to:[email protected]">[email protected]</a> [rest-discuss] <span dir= =3D"ltr"><<a href=3D"mailto:[email protected]" target= =3D"_blank">[email protected]</a>></span> wrote:<br> <blockquote class=3D"gmail_quote" style=3D"border-left:1px #ccc solid;"> <u></u> =20 <div style=3D"background-color:#fff;"> <span>=C2=A0</span> <div> <div> <div> =20=20=20=20=20=20 =20=20=20=20=20=20 <p>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<b= r> be "On" or "Off."<br> <br> One can PUT to /state , changing /state to either "On" or "O= ff."<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<b= r> 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 principle= s,<br> particularly regarding idempotency. In short, can one safely toggle?<br> <br> Any suggestions?<br> <br> Thanks,<br> Robby<br> <br> </p> </div> =20=20=20=20=20 =20=20=20=20 <div style=3D"color:#fff;min-height:0;"></div> </div> =20=20 </div></div></blockquote></div><br></div> </p> </div> =20=20=20=20=20 <!--~-|**|PrettyHtmlStart|**|-~--> <div style=3D"color: #fff; height: 0;">__._,_.___</div> =20=20=20=20=20=20=20=20=20=20 =20=20 =20 =20=20=20=20 <div style=3D"clear:both"> </div> <div id=3D"fromDMARC" style=3D"margin-top: 10px;"> <hr style=3D"height:2px ; border-width:0; color:#E3E3E3; background= -color:#E3E3E3;"> Posted by: Keith P Hassen <[email protected]> <hr= style=3D"height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E= 3E3;"> </div> <div style=3D"clear:both"> </div> <table cellspacing=3D4px style=3D"margin-top: 10px; margin-bottom: 10px= ; color: #2D50FD;"> <tbody> <tr> <td style=3D"font-size: 12px; font-family: arial; font-weight: bo= ld; padding: 7px 5px 5px;" > <a style=3D"text-decoration: none; color: #2D50FD= " href=3D"https://groups.yahoo.com/neo/groups/rest-discuss/conversations/me= ssages/19660;_ylc=3DX3oDMTJxZzlxbGNtBF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3J= wc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NjYwBHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTQwND= kxMTE2OA--?act=3Dreply&messageNum=3D19660">Reply via web post</a> </td> <td>•</td> <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p= x 5px;" > <a href=3D"mailto:[email protected]?subject=3DRe%3A%20%5Br= est-discuss%5D%20RESTful%20Toggle" style=3D"text-decoration: none; color: #= 2D50FD;"> Reply to sender </a> </td> <td>•</td> <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p= x 5px;"> <a href=3D"mailto:[email protected]?subject=3DRe%3A%= 20%5Brest-discuss%5D%20RESTful%20Toggle" style=3D"text-decoration: none; co= lor: #2D50FD"> Reply to group </a> </td> <td>•</td> <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p= x 5px;" > <a href=3D"https://groups.yahoo.com/neo/groups/rest-discuss/con= versations/newtopic;_ylc=3DX3oDMTJlbzZqaGJzBF9TAzk3MzU5NzE0BGdycElkAzQzMTky= NTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTQwNDkxMTE2OA-= -" style=3D"text-decoration: none; color: #2D50FD">Start a New Topic</a> </td> <td>•</td> <td style=3D"font-size: 12px; font-family: arial; padding: 7px 5p= x 5px;color: #2D50FD;" > <a href=3D"https://groups.yahoo.com/neo/groups/= rest-discuss/conversations/topics/19657;_ylc=3DX3oDMTM2NmRsZWgzBF9TAzk3MzU5= NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BG1zZ0lkAzE5NjYwBHNlYwNmdHI= Ec2xrA3Z0cGMEc3RpbWUDMTQwNDkxMTE2OAR0cGNJZAMxOTY1Nw--" style=3D"text-decora= tion: none; color: #2D50FD;">Messages in this topic</a> (4) </td> </tr> </tbody> </table> =20=20=20=20=20=20=20=20 <!------- Start Nav Bar ------> =20 <!-- |**|begin egp html banner|**| --> <div id=3D"ygrp-vital" style=3D"background-color: #f2f2f2; font-family: Ver= dana; font-size: 10px; margin-bottom: 10px; padding: 10px;"> <span id=3D"vithd" style=3D"font-weight: bold; color: #333; text-transf= orm: uppercase; "><a href=3D"https://groups.yahoo.com/neo/groups/rest-discu= ss/info;_ylc=3DX3oDMTJlYzk0cWk3BF9TAzk3MzU5NzE0BGdycElkAzQzMTkyNTUEZ3Jwc3BJ= ZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQwNDkxMTE2OA--" style=3D"= text-decoration: none;">Visit Your Group</a></span> <ul style=3D"list-style-type: none; margin: 0; padding: 0; display: in= line;"> <li style=3D"border-right: 1px solid #000; font-weight: 700; di= splay: inline; padding: 0 5px; margin-left: 0;"> <span class=3D"cat"><a href=3D"https://groups.yahoo.com/neo/groups/re= st-discuss/members/all;_ylc=3DX3oDMTJmbGw1aW9rBF9TAzk3MzU5NzE0BGdycElkAzQzM= TkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0MDQ5MTEx= Njg-" style=3D"text-decoration: none;">New Members</a></span> <span class=3D"ct" style=3D"color: #ff7900;">2</span> </li> </ul> </div> <div id=3D"ft" style=3D"font-family: Arial; font-size: 11px; margin-top: 5p= x; padding: 0 2px 0 0; clear: both;"> <a href=3D"https://groups.yahoo.com/neo;_ylc=3DX3oDMTJkNGNjNTNnBF9TAzk3ND= c2NTkwBGdycElkAzQzMTkyNTUEZ3Jwc3BJZAMxNzA1NzAxMDE0BHNlYwNmdHIEc2xrA2dmcARzd= GltZQMxNDA0OTExMTY4" style=3D"float: left;"><img src=3D"http://l.yimg.com/r= u/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height=3D"15"= width=3D"137" alt=3D"Yahoo! Groups" style=3D"border: 0;"/></a> <div style=3D"color: #747575; float: right;"> • <a href=3D"https://i= nfo.yahoo.com/privacy/us/yahoo/groups/details.html" style=3D"text-decoratio= n: none;">Privacy</a> • <a href=3D"mailto:rest-discuss-unsubscribe@yah= oogroups.com?subject=3DUnsubscribe" style=3D"text-decoration: none;">Unsubs= cribe</a> • <a href=3D"https://info.yahoo.com/legal/us/yahoo/utos/term= s/" style=3D"text-decoration: none;">Terms of Use</a> </div> </div> <br> <!-- |**|end egp html banner|**| --> </div> <!-- ygrp-msg --> =20 <!-- Sponsor --> <!-- |**|begin egp html banner|**| --> <div id=3D"ygrp-sponsor" style=3D"width:160px; float:right; clear:none; m= argin:0 0 25px 0; background: #fff;"> <!-- Start Recommendations --> <div id=3D"ygrp-reco"> </div> <!-- End Recommendations --> </div> <!-- |**|end egp html banner|**| --> <div style=3D"clear:both; color: #FFF; font-size:1px;">.</div> </div> <img src=3D"http://geo.yahoo.com/serv?s=3D97359714/grpId=3D4319255/grpspI= d=3D1705701014/msgId=3D19660/stime=3D1404911168" width=3D"1" height=3D"1"> = <br> <img src=3D"http://y.analytics.yahoo.com/fpc.pl?ywarid=3D515FB27823A7407E&a= =3D10001310322279&js=3Dno&resp=3Dimg" width=3D"1" height=3D"1">=20 <div style=3D"color: #fff; height: 0;">__,_._,___</div> <!--~-|**|PrettyHtmlEnd|**|-~--> </body> <!--~-|**|PrettyHtmlStart|**|-~--> <head> <style type=3D"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; } =20=20 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.fi= le-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; }=20 #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;=20 }=20 --> </style> </head> <!--~-|**|PrettyHtmlEnd|**|-~--> </html> <!-- end group email --> --001a11c13b601d548604fdc25f8a--