前后端分离开发和混合开发的区别还是很大的。前后端分离我们需要遵循restful规范,先介绍什么是restful api规范
a.同一种数据的操作,只设置一个url路由。也就是根据请求方法来区分具体的处理逻辑。而不再设置多个增删改查的路由。
(1)可以基于FBV来通过请求方法的不同,处理不同的逻辑。
url(r'^order/', views.order),
def order(request):
if request.method == 'GET':
return HttpResponse('获取订单')
elif request.method == 'POST':
return HttpResponse('创建订单')
elif request.method == 'PUT':
return HttpResponse('更新订单')
elif request.method == 'DELETE':
return HttpResponse('删除订单')
(2)可以基于CBV来实现处理不同的逻辑
url(r'^order/', views.OrderView.as_view()),
class OrderView(View):
def get(self,request,*args,**kwargs):
return HttpResponse(json.dumps(ret),status=201)
def post(self,request,*args,**kwargs):
return HttpResponse('创建订单')
def put(self,request,*args,**kwargs):
return HttpResponse('更新订单')
def delete(self,request,*args,**kwargs):
return HttpResponse('删除订单')
而两种方式中,最建议使用CBV的方式去写接口,更加简洁,不用判断了。
b. 域名建议
为了对用户使用的url和网页中使用的接口api进行区别,设置如下规则
(1)子域名的方式区分(需要解决跨域的问题):
www.baidu.com (用户在浏览器中输入的地址,可以访问网站页面)
但是网页需要到后台请求接口,获取数据,那么接口的api应该如何命名呢?
api.baidu.com/v1/login.json
用户一看到域名是以api开头的,就知道是接口,返回的是json数据。
(2)URL的方式进行区分(不需要解决跨域问题):
www.baidu.com (用户使用的URL)
www.baidu.com/api/v1/login.json
不管使用哪种方式,就是为了能够一眼区分出来这是一个api接口。
两种方式哪一种更好呢?
答案是第二种,因为第一种可能会出现跨域请求,也就是当域名不同或者端口不同的时候,都会出现跨域请求,而第二种保证了域名和端口的一致性,只是url不一样而已。
跨域:因为浏览器的同源策略,当你通过浏览器向www.baidu.com前端页面发送请求的时候,网页需要向后台请求接口,但是如果接口的域名和当前的域名不一致,就会出现跨源请求的错误,无法访问到页面。而跨源是网页向api发送请求之后,服务器响应了这个请求,但是是浏览器端把这一次请求的响应给阻止了,并不是在请求不同域名的接口时,服务端不会响应这个请求。跨源是浏览器端的阻止行为,而不是服务器端的。
c. 版本规则
两个版本共存的时候,应该将API的版本号放入URL。
api.example.com/api/v1/
另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。
d. 面向资源编程
将网络中的任何东西都看作是资源,对资源可以进行增删改查的操作,但是资源表示的是一个名称,如果一个url后面跟的是一个名词(单复数都可以),所用的名词往往与数据库的表格名对应,就表示要对这个资源进行增删改查的操作了。而get/post/delete/put是动词,所以url中不建议出现动词。
www.baidu.com/api/v1/order/ (遵循规范)
www.baidu.com/api/v1/orders/ (遵循规范)
www.baidu.com/api/v1/get_order/ (没有遵循规范)
e. HTTP方法规范
GET:从服务器上获取一个或者多个资源
POST:在服务器上新建一个资源
PUT:在服务器跟新全部资源
PATCH:在服务器更新部分资源
比如用户表就有用户名,密码,性别,如果是PUT就全部更新。如果是PATHCH就只更新密码。
f. 过滤规范
www.baidu.com/api/v1/orders/?status=1&page=2&offset
g. 状态码规范(状态码+code码)
后台提供的状态码,供前端使用。
200系列,300系列表示重定向,400系列表示客户端错误,500系列表示服务端错误(后台代码错误)。
但是只有状态码还是不够的,请求的状态太多,所以除了使用状态码表示状态以外,还应该有code码来表示更加详细的请求情况。
比如:支付宝的code码,20000,20001等
def get(self,request,*args,**kwargs):