RESTful 端点和数据库关系
RESTful endpoints and database relationships
我是 RESTful 开发新手。我正在开发一个显示州、地区和省份列表的小应用程序(使用 SpringBoot)。这是我的数据库图:
我在为资源创建端点时遇到问题。
创建这些端点是正确的:
/api/states **//List of all countries**
/api/states/{id} **//Show the single country**
/api/states/{id}/regions **//Show all regions**
/api/states/{id}/regions/{id} **//Show the individual region**
/api/states/{id}/regions/{id}/provinces **//Show all provinces**
/api/states/{id}/regions/{id}/provinces/{id} **//Show the individual province**
我意识到我的端点变得太长了,我认为这不是正确的过程。
根据您的经验,您可以推荐哪个建议?
谢谢
/api/states //List of all countries
/api/states/{id} //Show the single country
/api/states/{id}/regions //Show all regions
上面的端点很好。
问题存在于其余的嵌套中。假设区域和省份 ID 是全球唯一的,它们可以以相同的方式展平(不包括州)。
示例如下:
/api/regions/{id} //Show the individual region
/api/regions/{id}/provinces //Show all provinces
/api/provinces/{id} //Show the individual province
/api/provinces/{id}/towns //Show all towns
我完全同意你的观点:
/api/states - 是的,列出所有州
/api/states/{id} - 是的,显示一个状态
/api/states/{id}/regions - 是的,只是该州的地区
但现在我会走这条路:
/api/regions/{id} - 显示一个地区
/api/regions/{id}/provinces - 显示该地区的所有省份
/api/provinces/{id} - 显示一个省份
我发现每个请求只需要一个 {id}。
好吧,我想(在查看数据库模式之后)你所有的 states
、regions
和 provinces
已经有了唯一的标识符,你可以简单地继续一个 trim 来自 states
以外的所有资源的 /api/states
。这与使用查询参数过滤掉特定 ID 的 provinces
/regions
的事实相结合。
所以最终会得到以下端点
+----------------------------------------------+---------------------------------------------------------+
| Endpoint | Description |
+----------------------------------------------+---------------------------------------------------------+
| `/api/state` | Get a list of States |
| `/api/state/<id>` | Get a specific State |
| `/api/region` | Get a list of regions |
| `/api/region?state_id=<id>` | Get a list of regions from a specific state |
| `/api/region/<id>` | Get a specific region |
| `/api/province` | Get a list of provinces |
| `/api/province?state_id=<id>®ion_id=<id>` | Get a list of provinces based on state_id and region_id |
| `/api/province/<id>` | Get a specific Province |
+----------------------------------------------+---------------------------------------------------------+
现在,随着论文 routes/endpoints 的展开,关于如何通过 API 实际创建这些资源也很明显了。如果 API 的客户端知道资源的结果 <id>
,则使用 POST
或 PUT
。
另外请考虑@roman-vottner 在他上面的评论中所说的话。
相反,您可以使用一个控制器来处理所有查询组合。
例如,您可以将 Controller MapController 映射到 url /api/MapController。
在这个控制器中,我们可以定义一个方法,我们可以在其中放置我们的逻辑来处理不同类型的查询,如下例所示。
@RestController
@RequestMapping(value="/MapController")
public class MapController {
@RequestMapping(value="/getdata",method = RequestMethod.POST)
public void process(@RequestBody Map<String, Object> inputs)
throws Exception {
if(inputs.get("country_id")){
//fetch specific country_data
if(inputs.get("state_id")&&(state_id in country_data){
//fetch specific state_data
if(inputs.get("region_id")&&(region_id in state_data){
//fetch specific region_data
if(inputs.get("province_id")&&(province_id in region_data){
//fetch specific province_data
}
else{
return region_data.name //specific region details
}
}
else{
return state_data.name //specific state details
}
}
else{
return country_data.name //specific country details
}
}
else{
//Return All the countries
}
System.out.println(payload);
}
我是 RESTful 开发新手。我正在开发一个显示州、地区和省份列表的小应用程序(使用 SpringBoot)。这是我的数据库图:
我在为资源创建端点时遇到问题。 创建这些端点是正确的:
/api/states **//List of all countries**
/api/states/{id} **//Show the single country**
/api/states/{id}/regions **//Show all regions**
/api/states/{id}/regions/{id} **//Show the individual region**
/api/states/{id}/regions/{id}/provinces **//Show all provinces**
/api/states/{id}/regions/{id}/provinces/{id} **//Show the individual province**
我意识到我的端点变得太长了,我认为这不是正确的过程。 根据您的经验,您可以推荐哪个建议? 谢谢
/api/states //List of all countries
/api/states/{id} //Show the single country
/api/states/{id}/regions //Show all regions
上面的端点很好。
问题存在于其余的嵌套中。假设区域和省份 ID 是全球唯一的,它们可以以相同的方式展平(不包括州)。
示例如下:
/api/regions/{id} //Show the individual region
/api/regions/{id}/provinces //Show all provinces
/api/provinces/{id} //Show the individual province
/api/provinces/{id}/towns //Show all towns
我完全同意你的观点:
/api/states - 是的,列出所有州
/api/states/{id} - 是的,显示一个状态
/api/states/{id}/regions - 是的,只是该州的地区
但现在我会走这条路:
/api/regions/{id} - 显示一个地区
/api/regions/{id}/provinces - 显示该地区的所有省份
/api/provinces/{id} - 显示一个省份
我发现每个请求只需要一个 {id}。
好吧,我想(在查看数据库模式之后)你所有的 states
、regions
和 provinces
已经有了唯一的标识符,你可以简单地继续一个 trim 来自 states
以外的所有资源的 /api/states
。这与使用查询参数过滤掉特定 ID 的 provinces
/regions
的事实相结合。
所以最终会得到以下端点
+----------------------------------------------+---------------------------------------------------------+
| Endpoint | Description |
+----------------------------------------------+---------------------------------------------------------+
| `/api/state` | Get a list of States |
| `/api/state/<id>` | Get a specific State |
| `/api/region` | Get a list of regions |
| `/api/region?state_id=<id>` | Get a list of regions from a specific state |
| `/api/region/<id>` | Get a specific region |
| `/api/province` | Get a list of provinces |
| `/api/province?state_id=<id>®ion_id=<id>` | Get a list of provinces based on state_id and region_id |
| `/api/province/<id>` | Get a specific Province |
+----------------------------------------------+---------------------------------------------------------+
现在,随着论文 routes/endpoints 的展开,关于如何通过 API 实际创建这些资源也很明显了。如果 API 的客户端知道资源的结果 <id>
,则使用 POST
或 PUT
。
另外请考虑@roman-vottner 在他上面的评论中所说的话。
相反,您可以使用一个控制器来处理所有查询组合。 例如,您可以将 Controller MapController 映射到 url /api/MapController。 在这个控制器中,我们可以定义一个方法,我们可以在其中放置我们的逻辑来处理不同类型的查询,如下例所示。
@RestController
@RequestMapping(value="/MapController")
public class MapController {
@RequestMapping(value="/getdata",method = RequestMethod.POST)
public void process(@RequestBody Map<String, Object> inputs)
throws Exception {
if(inputs.get("country_id")){
//fetch specific country_data
if(inputs.get("state_id")&&(state_id in country_data){
//fetch specific state_data
if(inputs.get("region_id")&&(region_id in state_data){
//fetch specific region_data
if(inputs.get("province_id")&&(province_id in region_data){
//fetch specific province_data
}
else{
return region_data.name //specific region details
}
}
else{
return state_data.name //specific state details
}
}
else{
return country_data.name //specific country details
}
}
else{
//Return All the countries
}
System.out.println(payload);
}