ola*_*nod 6 rest serialization json hateoas hal-json
我对REST比较陌生,但我一直在做关于RESTful应该是什么的功课.现在我正在尝试为我的模型创建一个RESTful api,它实现了一个与其他模型有关系的JSON + HAL序列化器.
python中的示例模型:
class Category(Model):
name = CharField()
parent = ManyToOneField(Category)
categories = OneToManyField(Category)
products = ManyToManyField(Product)
class Product(Model):
name = CharField()
price = DecimalField()
related = ManyToManyField(Product)
categories = ManyToManyField(Category)
Run Code Online (Sandbox Code Playgroud)
假设我们有一个类别"目录",其子类别"食物"与产品"汉堡"和"热狗"都是相关的.
第一个问题.类别和产品应该是资源,所以他们需要一个URI,我应该在我的模型实现一个URI区域,并将其存储在数据库中或以某种方式在运行时计算的话,大约多标识符(URI)是什么?
第二个问题.可发现性,在Hal格式中应该"GET /"和不同的节点返回以使api容易被自己发现.
{
"_links":{
"self":{
"href":"/"
},
"categories":[
{
"href":"/catalog"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
第三个问题.添加为属性,嵌入或链接.示例"GET/catalog/food":
{
"_links":{
"self":{
"href":"/catalog/food"
}
},
"name":"food",
"parent":"/catalog",
"categories":[],
"products":[
"/products/burger",
"/products/hot-dog"
]
}
{
"_links":{
"self":{
"href":"/catalog/food"
},
"parent":{
"href":"/catalog"
},
"categories":[
],
"products":[
{
"href":"/products/burger"
},
{
"href":"/products/hot-dog"
}
]
},
"name":"food"
}
{
"_links":{
"self":{
"href":"/catalog/food"
}
},
"name":"food",
"_embedded":{
"parent":{
"_links":{
"self":{
"href":"/catalog"
}
},
"name":"catalog",
...
},
"categories":[
],
"products":[
{
"_links":{
"self":{
"href":"/products/burger"
}
},
"name":"burger",
...
},
{
"_links":{
"self":{
"href":"/products/hot-dog"
}
},
"name":"hot-dog",
...
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
第四个问题.返回结构时我应该有多深.示例"GET/catalog
{
"_links":{
"self":{
"href":"/catalog"
}
},
"name":"catalog",
"parent":null,
"categories":[
{
"name":"food",
"parent":{...},
"categories":[],
"products":[
{
"name":"burger",
"price":"",
"categories":[...],
"related":[...]
},
{
"name":"hot-dog",
"price":"",
"categories":[...],
"related":[...]
}
]
}
],
"products": []
}
Run Code Online (Sandbox Code Playgroud)
关于第一个问题:我不会将URI存储在数据库中.您可以在运行时轻松地在控制器内计算它们,并且控制器负责关注URI.通过这种方式,您可以保持模型和API的分离,如果您决定在将来更改API结构,则无需使用新URI更新整个数据库.
关于多个标识符,我不确定问题是什么,但在我看来,它与数据库无关,它是路由器和控制器应该关心如何处理任何URI.
关于第二个问题:首先,作为旁注:我会将单词类别作为URI的一部分.例如,我有http://domain.com/api/categories/catalog/food.通过这种方式,您可以使API更具描述性并且更具"黑客"性,这意味着用户应该能够删除/catalog/food部件并期望收到包含所有可用类别的集合.
现在,关于GET应该返回以允许发现的内容:我认为已经从您的URI结构中明确了这一点.当用户点击时,GET /categories他希望获得一个包含类别的列表(每个类别的名称和URI,以保持轻量级),并且当他跟随其中一个URI时,GET /categories/catalog他应该接收属性catalog类别的资源.同样,当他想要时GET /products/burger,他应该收到一个包含模型中所有属性的产品资源.您可能需要查看有关响应结构的示例.
关于第三个问题:同样的例子可以帮助你形成结构.我认为你的第二种反应方式更接近于此,但我还要添加一个name字段,而不仅仅是href.
关于第4个问题:当GET请求需要一组资源(比如GET /categories)时,我建议只提供每个资源的必要条件,即每个资源的名称和URI,并且只有当用户遵循所需的URI时,才能收到其余的资源.信息.
在你的榜样,catalog是一种资源,所以对GET /categories/catalog我将包括过程中的name资源(目录)和自身的链接,并为parent,sub-categories和products那些与它,我只想提供的名称和URI每个,以保持清醒.但是:这是关于设计API的一般想法.在你的实际问题中,你应根据您的具体业务问题来决定.我的意思是,如果您的API是关于带有类别和菜肴的餐馆菜单,您可能想要包括价格或小描述,即使不是响应实际产品而是回复产品系列,因为可能对您的用户而言,一个重要的信息.因此,通常,在响应资源列表时提供所有必要的信息(您只知道这些问题是什么),并在响应特定资源时提供资源的所有详细信息.
| 归档时间: |
|
| 查看次数: |
4454 次 |
| 最近记录: |