Статьи

Клиент RESTEasy: следующее поколение

Как выглядит 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-вызова в трех строках. Цель кода довольно ясна (по крайней мере, я думаю, что это понятно … пожалуйста, прокомментируйте).

сравнение

Есть несколько ключевых отличий между версией Билла и моей версией:

  1. Я использую конкретный класс вместо интерфейса.

    • Это ускорило мою разработку, поскольку теперь это выглядит и действует как ресурс на стороне сервера. Это изменение позволило мне использовать существующую серверную инфраструктуру для упрощения разработки прототипа.
    • Это также позволит классу инкапсулировать некоторые интересные функции, связанные с обработкой тела клиента. По сути, этот класс становится богатым предметным объектом.
  2. Я добавил @StatusValue
  3. Я повторно использовал существующую аннотацию JAX-RS (например, @HeaderParam, @CookieParam и т. Д.)
  4. Замена объекта 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 действительно новаторские. Он дал мне свободу работать над этим, и мне было весело делать это. Как я уже говорил ранее, у меня уже есть опытный образец …

Я определенно заинтересован в обратной связи. Если у вас есть какие-либо комментарии, улучшения, проблемы или вы просто хотите, чтобы эта функция была выпущена как можно скорее, просто дайте мне знать.

Обновление:  я понял, что я не избежал <в моем коде … теперь, когда я избежал его, мой код должен выглядеть намного более интуитивным.

С http://www.jroller.com/Solomon