RESTful架構,目前是比較流行的一種互聯網軟件架構。REST,即Representational State Transfer的縮寫。
說白點就是網站即軟件,再白點就是一個服務軟件支持http的四種方法:
GET用來獲取資源,POST用來新建資源、更新資源,PUT用來更新資源,DELETE用來刪除資源。
並對外提供一個或多個URI,每個URI對應一個資源;客戶端通過URI配合上面的方法就可以和服務
段的軟件交互。客戶端主要是瀏覽器,使用restful框架的軟件對http的支持也為了web應用帶來方便。
REST這個詞,是Roy Thomas Fielding在他2000年的博士論文中提出的。他的貢獻很多,
可以了解一下。本人工作的方向是SDN,也算是比較潮的東東,其中floodlight就用到了restful框架。
開發者為軟件開發出一些功能,並提供URI api,用戶就可以利用瀏覽器、curl等工具通過提供的URI
從軟件中獲得想要的信息或者設置軟件的功能。
對於發開者來說,就是提供URI和URI對應的資源,並將他們對應上,類似dicts={'/path?':resource}。
比如重寫http GET方法:首先獲得客戶端請求的url,解析url然后判斷其對應的URI,由於URI與應一個資源,
那么url就可以訪問這個資源了。具體實現上資源也就是方法或者一個類,要看具體實現了。
下面來個很簡單的例子,因為對於真正功能強大的restful來說,這個例子有幾點不足,但是作為簡單的演示,
應該夠了。
1 #-*-coding:UTF-8-*- 2 import socket,sys,urllib 3 from BaseHTTPServer import * 4 5 class Restful(BaseHTTPRequestHandler): #所有rest的父類 6 def __init__(self,request, client_address, server): 7 BaseHTTPRequestHandler.__init__(self,request, client_address, server) 8 self.dp=None 9 self.router=None 10 11 def basepath(self): 12 pass 13 def getresetlet(self): 14 pass 15 def send(self,src): 16 self.send_response(200) 17 self.send_header("Content-type", "text/html") 18 self.end_headers() 19 self.wfile.write(src) 20 self.wfile.close() 21 def done(self): 22 self.dp=self.basepath() 23 self.router=self.getrestlet() 24 class Test(Restful): #測試1 25 def test(self): #這就是一個資源 26 return "{\"date\":\"2013-11-19\"}" 27 def do_GET(self): #重寫get方法給了通過客戶端請求的url找到對應的資源 28 self.done() 29 for key in self.router.keys(): 30 tmp=self.dp+key 31 if tmp in self.path: 32 self.send(self.router[key]()) #執行資源 33 def basepath(self): #這個簡單的說就是和下面函數中的路徑配合,即/wm/time 34 return "/wm" 35 def getrestlet(self): #這兒就是URI與資源對應,這里只有test資源,可以注冊多個 36 rr={} 37 rr['/time']=self.test 38 return rr 39 class testjson(Restful): #測試2 40 def testjson(self,vpc,vr): #這里比測試1復雜些,因為參數的值需要從url中獲得 41 src1="{\"vpc\":1,\"vrouter\":3,\"day\":[1,2,3]}" 42 src2="{\"vpc\":1,\"vrouter\":4,\"day\":[23,21,3]}" 43 src3="{\"vpc\":5,\"vrouter\":3,\"day\":[13,2,23]}" 44 tlist=[src1,src2,src3] 45 cmpvpc="\"vpc\":"+vpc 46 cmpvr="\"vrouter\":"+vr 47 for k in tlist: 48 if cmpvpc in k and cmpvr in k: 49 return k 50 def firewall(self): 51 return "{\"filter\":[\"baid.com/\",\"c.cn/\"],\"acl\":{\"accept\":123,\"reject\":321}}" 52 def do_GET(self): #重寫GET,解析url,這里的self.path類似:/ins/json?vpc=1&vrouter=3 53 self.done() 54 print self.path 55 if 'vpc' in self.path and 'vrouter' in self.path: 56 query=None 57 if '?' in self.path: 58 query = urllib.splitquery(self.path) 59 key=query[0]+'?' 60 param=query[1].split('&') #解析獲得屬性信息,傳遞給資源函數 61 pdict={} 62 for p in param: 63 tmp=p.split('=') 64 pdict[tmp[0]]=tmp[1] 65 for k in self.router.keys(): 66 if k in key: 67 self.send(self.router[k](pdict['vpc'],pdict['vrouter'])) #執行資源 68 elif 'firewall' in self.path: 69 self.send(self.router['/firewall']()) 70 else: 71 self.send("{}") 72 def basepath(self): 73 return "/ins" 74 def getrestlet(self): 75 rr={} 76 rr['/json?']=self.testjson #注冊資源 77 rr['/firewall']=self.firewall 78 return rr 79 80 81 try: 82 server=HTTPServer(('',8084),testjson) #測試2 83 server.serve_forever() 84 except KeyboardInterrupt: 85 sys.exit(0)
如果運行上面的程序,運行的是測試2,運行后此程序監聽8084。
此時在瀏覽器地址欄輸入http://127.0.0.1:8084/ins/json?vpc=1&vrouter=3
得到如下圖,本人使用的chrome,安裝插件后的效果。
輸入:http://127.0.0.1:8084/ins/firewall
這里僅僅作為演示,程序有有許多不足。對於好的框架,注冊資源不應該和資源在同一個類中,
basepath()與getrestlet()不應該在實現的資源類里(也就是上面的測試里),也使router沒起作用。
應該在另一個類里注冊,這樣可以通過不同的URI,兩個測試都應該能夠運行;還有就是使用的python
自帶的BaseHTTPServer模塊,並不適合做restful。
但是工作過程大體就是這樣,后續有時間會寫個python版的restful簡易框架。