Java 对于使用相同参数的多个REST API调用,最佳做法是什么

Java 对于使用相同参数的多个REST API调用,最佳做法是什么,java,spring,spring-boot,rest,spring-restcontroller,Java,Spring,Spring Boot,Rest,Spring Restcontroller,我有一个restapi列表,它接收各种参数,用于搜索、过滤并将数据返回前端 @GetMapping(value = "/api1", params = {"x,y,z,age,location"}) @GetMapping(value = "/api2", params = {"a,b,c,d,age,location"}) @GetMapping(value = "/api3", params

我有一个restapi列表,它接收各种参数,用于搜索、过滤并将数据返回前端

@GetMapping(value = "/api1", params = {"x,y,z,age,location"})
@GetMapping(value = "/api2", params = {"a,b,c,d,age,location"})
@GetMapping(value = "/api3", params = {"p,q,r,s,,age,location"})
@GetMapping(value = "/api4", params = {"p,q,r,s,,age,location"})
@GetMapping(value = "/api5", params = {"p,q,r,s,,age,location"})
正如您所注意到的,问题在于存在一些参数(年龄、位置),这些参数对于所有这些端点都是通用的

我们的计划是,我们可能需要为所有这些端点引入一个新参数,如“性别”。 是否有一种最佳实践可以跨API处理这些公共参数,这样我们就不需要修改每个控制器并添加新添加的请求参数

控制器的外观如下所示:

@RestController
public class UserFilterController {


    @GetMapping(path = "/api1")
    public ResponseEntity filterUserWithApi1(String x, String y, String z, String age, String location) {

        return new ResponseEntity(HttpStatus.OK);
    }

    @GetMapping(path = "/api2")
    public ResponseEntity filterUserWithApi2(String a, String b, String c, String age, String location) {

        return new ResponseEntity(HttpStatus.OK);
    }

    @GetMapping(path = "/api3")
    public ResponseEntity filterUserWithApi3(String d, String e, String f, String age, String location) {

        return new ResponseEntity(HttpStatus.OK);
    }

    @GetMapping(path = "/api4")
    public ResponseEntity filterUserWithApi4(String g, String s, String h, String age, String location) {

        return new ResponseEntity(HttpStatus.OK);
    }

    @GetMapping(path = "/api5")
    public ResponseEntity filterUserWithApi5(String j, String k, String l, String age, String location) {

        return new ResponseEntity(HttpStatus.OK);
    }

}

如果路径不同,则无需在
@GetMapping
注释中设置
参数
字段,只需执行以下操作:

@GetMapping(path = "/api1")
public void myFunction( @RequestParam("age") String age, @RequestParam("location") String location, ... ) {
...
}

如果是相同的路径,您也可以这样做,但您需要在RequestParam注释中添加“required=false”,并手动处理当某些字段存在或不存在时的操作

如果路径不相同,您不需要在
@GetMapping
注释中设置
参数
字段,您只需执行以下操作:

@GetMapping(path = "/api1")
public void myFunction( @RequestParam("age") String age, @RequestParam("location") String location, ... ) {
...
}

如果是相同的路径,您也可以这样做,但您需要在RequestParam注释中添加“required=false”,并手动处理当某些字段存在或不存在时该怎么办

如果您不知道请求中将有多少个参数,您可以使用@RequestParam作为如下映射-

@GetMapping(path = "/api1")
public void test(@RequestParam Map<String, String> parameters) {
    //TODO
    String value1 = parameters.get("key1");
    ........
}
或-

请求-

/api1/24/earth?x=x_value&y=y_value&z=z_value
或-

请求-

/api1/<age_value>/<location_value>/<x_value>/<y_value>/<z_value>
/api1/////

如果您不知道请求中将有多少个参数,您可以使用@RequestParam作为映射,如下所示-

@GetMapping(path = "/api1")
public void test(@RequestParam Map<String, String> parameters) {
    //TODO
    String value1 = parameters.get("key1");
    ........
}
或-

请求-

/api1/24/earth?x=x_value&y=y_value&z=z_value
或-

请求-

/api1/<age_value>/<location_value>/<x_value>/<y_value>/<z_value>
/api1/////

我相信您的查询参数是一个具有多个值的单一属性,并且年龄/位置是最后出现的一些其他强制查询参数。这就是我将如何编写已知给定参数的控制器

         @GetMapping(path = "/test")
        public Map<String, String> test(@RequestParam("alphabets") Set<String> alphabets,
                                        @RequestParam("age") int age,
                                        @RequestParam("location") String location) {
            final Map<String, String> responseMap = new HashMap<>();
            responseMap.put("alphabets", alphabets.toString());
            responseMap.put("age", Integer.toString(age));
            responseMap.put("location", location);
            return responseMap;
        }
现在,您可以基于字母表中的值创建连接


谢谢。

我相信您的查询参数是一个具有多个值的单一属性,年龄/位置是最后出现的一些其他强制查询参数。这就是我将如何编写已知给定参数的控制器

         @GetMapping(path = "/test")
        public Map<String, String> test(@RequestParam("alphabets") Set<String> alphabets,
                                        @RequestParam("age") int age,
                                        @RequestParam("location") String location) {
            final Map<String, String> responseMap = new HashMap<>();
            responseMap.put("alphabets", alphabets.toString());
            responseMap.put("age", Integer.toString(age));
            responseMap.put("location", location);
            return responseMap;
        }
现在,您可以基于字母表中的值创建连接


谢谢。

您能分享一下控制器吗definition@silentsudo,我已经将控制器添加到帖子中。我已经添加了我的回复。您可以共享控制器吗definition@silentsudo,我已经在帖子中添加了控制器。我已经添加了我的回复。谢谢@Prim,我在这篇帖子中只使用了param字段以便于阅读。在我的代码中,我使用了你建议的结构。谢谢@Prim,我在这篇文章中只使用了param字段以便于阅读。在我的代码中,我使用的是您建议的结构。这将导致大量的空检查,并且容易出错的代码将出现在控制器中,始终最好确保控制器消耗的是尽可能多的东西,留给客户的可能是门窗敞开的房子。@silentsudo同意。@silentsudo我已经用多个选项更新了答案,谢谢。这将导致大量空检查,并且控制器中会出现易出错的代码,始终最好确保留给客户的是尽可能多且可能多的门窗敞开的房子。@silentsudo同意。@silentsudo我已经用多个选项更新了答案,谢谢。