我有一个问题是正确有效地表示rest api中的资源。
我在我的数据库中有两个表产品和类别,类别以层次结构方式存储:id_category
和parent_id
以及“叶子”类别“包含”产品。
客户通过.../api/categories/sub/{parentid}.
在服务器中,我执行类似SELECT id_cat, name_cat FROM categories WHERE parent_id = {parentid}
的查询,这会将子类别返回给客户端,这没关系,但是当客户端点击叶子类别时,我必须显示与之相关的产品此类别和客户端请求是相同的.../api/categories/sub/{parentid}
,在这种情况下,此请求会生成产品列表,而不是子类别列表!!!
示例在php中使用Slim
$app->get(
'/categories/sub/:parentid',
function ($parentid) {
$sql = "select idcat, nome_categoria FROM categorie WHERE parentid =".$parentid;
try {
$db = getConnection();
$stmt = $db->query($sql);
$cat = $stmt->fetchAll(PDO::FETCH_ASSOC);
$db = null;
if (count($cat)>0) {
deliver_response("sub categories", $cat);
} else {
$sql = "select p.nome_prodotto FROM categorie AS c JOIN cat_to_prod AS k ON c.idcat = k.idcat JOIN prodotti AS p ON k.codprod = p.codprod WHERE c.idcat = ".$parentid;
$db = getConnection();
$stmt = $db->query($sql);
$prod = $stmt->fetchAll(PDO::FETCH_ASSOC);
$db = null;
if (count($prod)>0) {
deliver_response("products", $prod);
} else {
deliver_response("no products found", null);
}
}
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
);
我认为在休息解决方案中这是错误的,但如何解决呢?
我的想法是当客户端在叶子类别上发出请求../api/categories/sub/{parentid}
时返回“未找到的消息”,并发送另一个请求以显示具有URI .../products/category/{id_leaf_category}
的类别的产品,但这需要两个请求由客户提供,它可能是广阔的。
您怎么看?
感谢回复并抱歉我的英语不好
答案 0 :(得分:1)
使用超媒体并包含指向更多类别或产品的子集的链接。
如果回复包含“类别”链接,则客户端知道它将通过跟踪该链接进入下一级别的类别。
如果回复包含“产品”链接,则客户知道它可以通过该链接获取当前类别的所有产品。
让这些链接引用不同的资源(正如你自己建议的那样)是很自然的。
超媒体当然不是必需的 - 您可以使用布尔标志和硬编码客户端对可能的URL的了解来做同样的事情。
另一种方法是在同一响应中返回两个类和产品:
{
"products": [ array of products, possibly empty ],
"categories": [ array of sub-categories (including links to them), possibly empty ],
}
此解决方案允许您公开非叶类别的产品。
是否返回“404 Not found”是一场陈旧的辩论,没有权威的答案。有些人喜欢使用空列表返回200 OK(没有子类别) - 其他人更喜欢404未找到(没有子类别集合)。