Статьи

В эпоху REST мертвый вызов удаленной процедуры Java?

Когда вы пишете веб-сервисы в наше время, вы можете быть уверены, что REST будет вашим первым выбором и, вероятно, вашим единственным выбором. Иногда вам просто нужно быстро создать что-то похожее на RPC, которое может быть вызвано простым HTTP-вызовом и использует JSON, как все классные ребята в блоке. Введите  JSON-RPC .

JSON-RPC

RPC действительно получил дурную славу благодаря некоторым стандартам, которые использовались для его достижения. Большинство разработчиков вздрагивают, сталкиваясь с WSDL и конвертами SOAP. Тем не менее, RPC по-прежнему имеет много вариантов использования, например, для удаленного взаимодействия между бизнес-интерфейсом и выделенным фоном. Большинство пользователей Spring знакомы с функциями удаленного взаимодействия, которые он предоставляет, включая HTTP-вызов (с использованием сериализации Java), JMS и простой старый RMI. JSON-RPC может быть очень хорошей заменой в таких условиях и обеспечивает простой способ тестирования и вызова вашего API с использованием только браузера.

JSON-RPC является официальным стандартом, теперь в версии 2.0. Он использует полезную нагрузку JSON для определения как запроса, так и ответа на вызов RPC. Стандартный вызов JSON-RPC выглядит следующим образом:

{
  "id":1234,
  "method":"myRpcMethod",
  "params":["test"]
}

С помощью JSON-RPC вы можете выбрать выделенную конечную точку для каждой службы или одну конечную точку, различая службы на уровне сервера, добавив префикс имени метода к идентификатору службы.

Ответ будет либо результатом вызова, либо структурой, возвращающей информацию об ошибке в случае сбоя вызова.

Использование JSON-RPC с Java

Существует несколько библиотек JSON-RPC. Однако, как я выяснил, на самом деле стоит обратить внимание только на одно, особенно если вы используете Spring:  jsonrpc4j . Он использует Jackson для обеспечения отображения между POJO и JSON и поэтому может быть легко расширен для поддержки множества библиотек Java, таких как поддержка сериализации для Joda Time и новый Money API.

С jsonrpc4j представить сервис как сервис JSON очень просто. Я собираюсь дать вам базовую настройку для предоставления сервиса в Spring Boot, но вы можете найти больше информации в документации проекта.

Например, скажем, у нас есть сервис, который должен быть представлен следующим образом:

public interface MyService {
  String sayHelloWorld(String name);
}

public class MyServiceImpl implements MyService {
  public String sayHelloWorld(String name) {
    return "Hello world, " + name;
  }
}

Чтобы предоставить этот сервис JSON-RPC с Spring Boot, вам нужен следующий конфигурационный файл с jsonrpc4j:

@SpringBootApplication
public class RpcApplication {
  public static void main(String[] args) {
    SpringApplication.run(RpcApplication.class);
  }

  @Bean
  public MyService myService() {
    return new MyServiceImpl();
  }

  @Bean(name = "/rpc/myservice")
  public JsonServiceExporter jsonServiceExporter() {
    JsonServiceExporter exporter = new JsonServiceExporter();
    exporter.setService(myService());
    exporter.setServiceInterface(MyService.class);
    return exporter;
  }
}

Вот и все. Запустите приложение Boot и выполните следующую  curl команду:

curl -v -X POST -d '{"id":0, "method":"sayHelloWorld", "params":["John Doe"]}' http://localhost:8080/rpc/myservice

Вы должны получить следующий ответ:

{"response": "Hello world, John Doe"}

И это все для демонстрации методов JSON-RPC с помощью Spring Boot. Очень просто, очень быстро и очень мощно. Лично мне очень нравятся API-интерфейсы JSON-RPC для внутреннего использования, потому что у него такая маленькая кривая обучения. Хотя это определенно не REST, он позволяет быстро предоставлять сервис через интерфейс HTTP с структурами данных JSON. API-интерфейсы JSON-RPC могут быть отличным дополнением к вашим API-интерфейсам REST. Нет сомнений в том, что API-интерфейсы REST предпочтительнее для внешних веб-сервисов, но для внутренней связи или внутренних API-интерфейсов JSON-RPC может обеспечить быструю альтернативу экстернализации сервисов, не беспокоясь о том, чтобы сопоставить все с ресурсами RESTful.