[Representational State Transfer, REST%|%REST] stands for representational state transfer [[Add pointers to other discussions of REST here]] ** Description ** '''REST''' is an architectural style in which a provider transfers a certain representation of the current incarnation of a requested resource, along with the available transitions to other resources from that resource at that point. Each request is stateless in the sense that the receiver of the request does not rely on any previous requests to decide what the request means. A request itself provides an identifier for the desired resource, along with one of the standard methods, and each response communicates one of a the standard result codes. The available transistions should be derived by the client soley from the response, and not from any interpretation of the identifier for a resource or from other external data. ''You can’t have evolvability if clients have their controls baked into their design at deployment. ... But that alone is still not enough for evolvability. Hypermedia allows application controls to be supplied on demand, but we also need to be able to adapt the clients' understanding of representations (understanding of media types and their expected processing). That is where code-on-demand shines. ... The techniques that developers learn from managing in-house software, where they might reasonably believe they have control over deployment of both clients and servers, simply don’t apply to network-based software intended to cross organizational boundaries. This is precisely the problem that REST is trying to solve: how to evolve a system gracefully without the need to break or replace already deployed components. '' : Roy Fielding, [https://www.infoq.com/articles/roy-fielding-on-versioning/%|%infoq], 2014-12-17 The [tcllib] module https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/rest/rest.md%|%rest%|% privides a [tcl]-implementation for REST. I was trying to get the google docs interface to support "update" but had no joy. [restful gdocs] ** A REST Utility ** [DKF]: This is my REST client support class. ====== package require Tcl 8.5 package require http package require TclOO # RESTful service core package provide rest 0.1 # Support class for RESTful web services. This wraps up the http package to # make everything appear nicer. oo::class create REST { variable base wadls acceptedmimetypestack constructor baseURL { set base $baseURL my LogWADL $baseURL } # TODO: Cookies! method ExtractError {tok} { return [http::code $tok],[http::data $tok] } method OnRedirect {tok location} { upvar 1 url url set url $location # By default, GET doesn't follow redirects; the next line would # change that... #return -code continue set where $location my LogWADL $where if {[string equal -length [string length $base/] $location $base/]} { set where [string range $where [string length $base/] end] return -level 2 [split $where /] } return -level 2 $where } method LogWADL url { return;# do nothing set tok [http::geturl $url?_wadl] set w [http::data $tok] http::cleanup $tok if {![info exist wadls($w)]} { set wadls($w) 1 puts stderr $w } } method PushAcceptedMimeTypes args { lappend acceptedmimetypestack [http::config -accept] http::config -accept [join $args ", "] return } method PopAcceptedMimeTypes {} { set old [lindex $acceptedmimetypestack end] set acceptedmimetypestack [lrange $acceptedmimetypestack 0 end-1] http::config -accept $old return } method DoRequest {method url {type ""} {value ""}} { for {set reqs 0} {$reqs < 5} {incr reqs} { if {[info exists tok]} { http::cleanup $tok } set tok [http::geturl $url -method $method -type $type -query $value] if {[http::ncode $tok] > 399} { set msg [my ExtractError $tok] http::cleanup $tok return -code error $msg } elseif {[http::ncode $tok] > 299 || [http::ncode $tok] == 201} { set location {} if {[catch { set location [dict get [http::meta $tok] Location] }]} { http::cleanup $tok error "missing a location header!" } my OnRedirect $tok $location } else { set s [http::data $tok] http::cleanup $tok return $s } } error "too many redirections!" } method GET args { return [my DoRequest GET $base/[join $args /]] } method POST {args} { set type [lindex $args end-1] set value [lindex $args end] set m POST set path [join [lrange $args 0 end-2] /] return [my DoRequest $m $base/$path $type $value] } method PUT {args} { set type [lindex $args end-1] set value [lindex $args end] set m PUT set path [join [lrange $args 0 end-2] /] return [my DoRequest $m $base/$path $type $value] } method DELETE args { set m DELETE my DoRequest $m $base/[join $args /] return } export GET POST PUT DELETE } # Local Variables: # mode: tcl # tab-width: 4 # End: ====== <> Tcllib | Internet