Как выглядит REST-клиент Next Generation? У Билла Бёрка было несколько идей … угадайте, кто их реализует? С уважением.
Мне нравится общее направление, в котором он шел. Помните ли вы, что Рой Филдинг выступил в 2008 году: API-интерфейсы REST должны быть управляемы гипертекстом ? Одним из следствий этого является то, что клиентское REST-приложение должно иметь один начальный URL-адрес «закладки», и с этого момента клиент взаимодействует с сервером на основе ссылок, которые возвращает сервер. Подход Билла заключается в использовании объектов Link для описания заголовков Link.
Версия Билла:
@ResponseMapping
@ExpectedCode(200)
public interface MyResponse {
@Body
public Customer getCustomer();
@LinkHeader
public Link getNext();
@LinkHeader("last")
public Link getLastCustomer();
@Header("ETag")
public String getHash();
}
Это на шаг впереди текущего клиента RESTEasy, который был довольно приятным с самого начала. Однако…
Моя версия
Объекты ссылок хороши, но у меня есть альтернатива, которая для меня кажется немного более сексуальной и немного более ориентированной на Java:
@ResponseMapping(status=200)
public class MyResponse {
public Callable<MyResponse> next;
public Callable<Status> remove;
@Body
public Customer customer;
@StatusValue
public int status;
@HeaderParam("ETag")
public String getHash();
// you can alternatively set an interface that matches the classic
// RESTEasy paradigm, which will automatically be proxied
@GET
@LinkHeader(relationship="next")
public setNext(Callable<MyResponse> next){
this.next = next;
}
@DELETE
@LinkHeader(title="remove")
public setNext(Callable<Status> remove){
this.remove = remove;
}
}
Код на стороне клиента будет выглядеть примерно так:
ClientRequestFactory factory = new ClientRequestFactory("http://mysite.com");
factory.setInterceptor(...);
MyResponse response = factory.createRequest("clientSearch?name=" + nameToSearch).getEntity(MyResponse.class);
MyResponse next = response.next.call();
next.remove.call();
Это сделало бы три HTTP-вызова в трех строках. Цель кода довольно ясна (по крайней мере, я думаю, что это понятно … пожалуйста, прокомментируйте).
сравнение
Есть несколько ключевых отличий между версией Билла и моей версией:
- Я использую конкретный класс вместо интерфейса.
- Это ускорило мою разработку, поскольку теперь это выглядит и действует как ресурс на стороне сервера. Это изменение позволило мне использовать существующую серверную инфраструктуру для упрощения разработки прототипа.
- Это также позволит классу инкапсулировать некоторые интересные функции, связанные с обработкой тела клиента. По сути, этот класс становится богатым предметным объектом.
- Я добавил @StatusValue
- Я повторно использовал существующую аннотацию JAX-RS (например, @HeaderParam, @CookieParam и т. Д.)
- Замена объекта Link на Callable.
Я хотел, чтобы Java-интерфейс был более ориентирован на удаленный вызов, но в то же время прямо выражал детали HTTP. Потребовался час или около того, чтобы возиться с моим прототипом, прежде чем Callable «позвал» меня.
Быстрый поиск по заголовку ссылки и использованию <atom: link ../>
Кроме того, мне пришлось использовать методы установки, потому что мне нужно было указать аннотации @ GET / @ DELETE, поскольку они могут применяться только к методам Java. Использование заголовков ссылок, вдохновленных <atom: link ../>, к сожалению, требует внеполосного описания метода HTTP, что не является идеальной ситуацией REST. Заголовки ссылок и <atom: link ../> используются способами, которые не были выражены в первоначальном видении использования ATOM Pub. Традиционное использование ATOM Link было CRUDdy (Create = POST, Read = GET, Update = PUT, Delete = DELETE). Текущее использование не всегда соответствует CRUD (например, какой VERB вы бы использовали для rel = «Pay»). Заголовки ссылок и <atom: link ../> не имеют места для VERB, поэтому практикующим REST пришлось использовать внеполосную информацию, чтобы сопоставить значение «rel» с конкретным VERB …. Короче говоря,Я бы предпочел иметь явный VERB как часть Link, но сейчас мне придется довольствоваться внеполосной документацией и компилировать аннотации времени …
В любом случае, если вы не понимаете (или ПОЛУЧАЕТЕ) то, что я сказал в последнем абзаце, не волнуйтесь, я буду более подробно останавливаться на этой философской идее в будущем. Эта запись в блоге была о реализации нового прототипа API клиента, а не о философии REST …
Следующие шаги
ИМХО, идеи Билла о клиентах Java REST действительно новаторские. Он дал мне свободу работать над этим, и мне было весело делать это. Как я уже говорил ранее, у меня уже есть опытный образец …
Я определенно заинтересован в обратной связи. Если у вас есть какие-либо комментарии, улучшения, проблемы или вы просто хотите, чтобы эта функция была выпущена как можно скорее, просто дайте мне знать.
Обновление: я понял, что я не избежал <в моем коде … теперь, когда я избежал его, мой код должен выглядеть намного более интуитивным.