我在节点js中编写REST api,它将执行sql查询并发送结果; 在请求中我需要发送WHERE条件;例如:
GET 127.0.0.1:5007/users //gets the list of users
GET 127.0.0.1:5007/users
id = 1 //gets the user with id 1
现在,条件从客户端传递到请求标头中的其余api。 在API I中使用sequelize,一个需要以特定形式(对象)接收WHERE条件的ORM;例如:有条件:
(x=1 AND (y=2 OR z=3)) OR (x=3 AND y=1)
这需要格式化为嵌套对象:
-- x=1
-- AND -| -- y=2
| -- OR ----|
| -- z=3
-- OR -|
|
| -- x=3
-- AND -|
-- y=1
所以对象将是:
Sequelize.or (
Sequelize.and (
{x=1},
Sequelize.or(
{y=2},
{z=3}
)
),
Sequelize.and (
{x=3},
{y=1}
)
)
现在我试图传递一个简单的字符串(例如"(x = 1 AND(y = 2 OR z = 3))OR(x = 3 AND y = 1)" ),但后来我需要一个服务器上的函数,可以转换所需对象中的字符串(我认为这个方法的优点是开发人员编写客户端,可以通过简单的方式传递where条件,比如使用sql ,此方法也与使用的ORM无关,如果我们需要更改服务器或使用不同的ORM,则无需更改客户端;
读取和转换条件的功能'字符串成为一个对象让我很头疼(我试图写一个没有成功,所以如果你有一些关于如何做这样的事情的例子......)
我想得到的是一条能够执行几乎任何类型的SQL查询并给出结果的路由:
现在我有一条不同的路线:
127.0.0.1:5007/users //to get all users
127.0.0.1:5007/users/1 //to get a single user
127.0.0.1:5007/lastusers //to get user registered in the last month
等我需要查询的其他表(我需要在客户端的每种请求的一个路由); 相反,我想只有一条路线,如:
127.0.0.1:5007/request
(调用此路线时,我会传递表名和条件'字符串)
您认为这个解决方案是一个很好的解决方案还是您通常使用其他方式来处理这类事情? 您是否知道如何编写一个函数来转换条件'字符串到所需的对象?
任何建议都将受到赞赏;)
答案 0 :(得分:1)
我强烈建议您不要将数据库模型的任何部分暴露给您的客户。这样做意味着您无法改变您所暴露的任何内容,而不会有破坏客户的风险。就您提供的内容而言,一个建议是您可以而且应该使用查询参数来减少您已获得的终端数量。
GET /users //to get all users
GET /users?registeredInPastDays=30 //to get user registered in the last month
GET /users/1 //to get a single user
显然" registeredInPastDays"应该重新命名为不那么笨拙的东西..它只是一个例子。
就条件字符串而言,网上应该有大量的解析器。语法看起来很简单。
答案 1 :(得分:0)
恕我直言,您的解决方案的主要缺点是您正在创建另一个用于查询数据的API。为什么如果已经创建了sthm?您应该使用现有的成熟查询API并专注于您的业务逻辑,而不是发明新的sthm。
例如,您可以从Odata获取查询语法。许多人长期以来一直在制定这一标准。他们已经考虑了查询API的不同用例和障碍。
答案 2 :(得分:0)
资源位于URI中。您可以使用或混合三种方式来解决它们:
具有一系列路径段的层次结构:
/users/john/posts/4711
非查询参数的分层结构:
/users/john/posts?minVotes=10&minViews=1000&tags=java
矩阵参数只影响一个路径段:
/users;country=ukraine/posts
这通常足够了,但它有maximum length等限制。在您的情况下,问题是您无法使用查询参数轻松描述and
和or
个连词。但您可以使用自定义或标准查询语法。例如,如果您想要找到福特除了卡普里以外的所有汽车或车辆,价格在10000美元到20000美元之间,Google会使用搜索参数
q=cars+OR+vehicles+%22ford%22+-capri+%2410000..%2420000
(%22
是转义"
,%24
转义为$
。
如果这不适用于您的情况并且您想要在URI之外传递数据,则格式只是您的品味。添加像X-Filter
这样的自定义标头可能是一种有效的方法。我倾向于使用POST
。虽然您只想查询数据,但如果您将请求视为搜索结果资源的创建,那么这仍然是RESTful:
POST /search HTTP/1.1
your query-data
您的服务器应该在Location标头中返回新创建的资源:
HTTP/1.1 201 Created
Location: /search/3
结果仍然可以缓存,您可以将其加入书签或发送链接。缺点是您需要额外的POST
。