REST - Скачать список пользователей - PullRequest
0 голосов
/ 05 октября 2018

Контекст:

Я хочу написать конечную точку, которая будет возвращать Collection пользователей на основе их имен пользователей.Как эти имена пользователей должны быть переданы в конечную точку REST - обратите внимание, что у меня (потенциально) может быть много имен пользователей (скажем,> 5000) ?

Решение №1:

Используйте конечную точку GET, объедините имена пользователей на стороне клиента и передайте их как один параметр запроса.Разделите параметр запроса на стороне сервера, чтобы получить список имен пользователей.

@RestController
public class UserController { 

    @GetMapping
    // able to deserialize `filename1,filename2` to List out of the box
    public Collection<User> getUser(@RequestParam List<String> usernames) {
        return userService.getUsersByUsername(usernames);
    }

}

Решение № 2:

Используйте конечную точку POST и передайте списокимена пользователей в качестве тела запроса.Несмотря на то, что они более чисты с точки зрения кодирования, в итоге я использую POST для извлечения данных.

@RestController
public class UserController { 

    @PostMapping
    public Collection<User> getUser(@RequestBody List<String> usernames) {
        return userService.getUsersByUsername(usernames);
    }

}

Вопросы:

  1. Какое из двух решенийбудет лучшим подходом?
  2. Есть ли у вас лучший подход для передачи списка имен пользователей в конечную точку?

Правки:

  • Я обновил подпись первого решения на основе предложений из ответов.Spring может десериализовать filename1,filename2 для вывода из коробки для @RequestParam.

Ответы [ 4 ]

0 голосов
/ 05 октября 2018

Я бы согласился со всеми ответами, приведенными выше.Я хотел бы указать еще один момент: если вы собираетесь отправлять запрос, вам может потребоваться увеличить объем полезной нагрузки, которую может получить сервер, объем почты по умолчанию (максимальный размер в байтах) при весенней загрузке составляет 2 МБ (в зависимости от вашего сервера).).Во время тестирования ваш код может нормально работать с 1000-2000 именами пользователей, но обязательно измените свойство, чтобы принимать больше байтов в запросе.

0 голосов
/ 05 октября 2018

POST выглядит в этом случае более чистым подходом, потому что -

  1. Отправка огромной строки в URL не является хорошей идеей, и есть вероятность ошибки
  2. Вынеобходимо написать дополнительный код (логику) для создания строки во внешнем интерфейсе и разбить ее на внутренний интерфейс.
  3. Отправка огромной строки в URL не масштабируется, поскольку существуют ограничения на длину URL.
0 голосов
/ 05 октября 2018

GET не ограничен, но браузер есть.Ваш серверный клиент, похоже, не является браузером, поэтому я бы сказал, что GET - это путь.

PS GET может получить тело (не так здорово, но POST тоже нелучшее совпадение).

Вам не нужно объединять строку и добавлять дополнительные вычисления на серверном сервере, GET может получить список отдельных строк.

ОБНОВЛЕНИЕ с примером:

@RestController
public class MyController {

    @GetMapping(value = "/test")
    public List<String> getTestParams(@RequestParam List<String> params) {
        return params;
    }
}    

Тест с 3000 параметрами

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestMyController {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testRequestWithParamsList() {    
        List<String> params = new ArrayList<>();
        for (int i = 0; i < 3000; i++) {
            params.add(String.valueOf(i));
        }

        List<String> result = restTemplate.getForObject(buildUrl(params),
                List.class);

        assertEquals(params, result);
    }

    private String buildUrl(List<?> params) {
        return "/test?params=" + getUrlParameter(params);

    }

    private String getUrlParameter(List<?> params) {
        return params.stream()
                .map(Object::toString)
                .collect(Collectors.joining(","));
    }
}    

Если вы используете tomcat, вы должны также указать свойство заголовка max http в application.properties

server.max-http-header-size=30000 
0 голосов
/ 05 октября 2018

Подход Get может привести к проблеме, так как длина URL-адреса ограничена, и тогда вам придется ограничить параметры запроса.

Хотя это не пост-запрос, но в вашем случае я думаю, что пост - единственный выход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...