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}。

好吧,我想(在查看数据库模式之后)你所有的 statesregionsprovinces 已经有了唯一的标识符,你可以简单地继续一个 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>&region_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>,则使用 POSTPUT

另外请考虑@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);

    }