Предоставление существующего API в качестве веб-службы - PullRequest
4 голосов
/ 31 января 2011

В настоящее время я работаю над задачей представить API в качестве веб-службы.Идея заключается в том, чтобы упаковать существующую бизнес-логику в JAR-файлах в WAR-файл и представить WAR-файл в виде веб-службы, которая возвращает строку XML свободной формы.Когда мы представляем существующий API в качестве веб-службы, достаточно ли того, чтобы мы предоставили доступ к файлу XSD & WSDL возвращенных данных строки XML?Это соглашение или стандартная практика?

Ответы [ 2 ]

14 голосов
/ 31 января 2011

Это зависит от того, используете ли вы SOAP или REST.SOAP более ограничен;в результате более вероятно, что у вас будет файл WSDL для генерации классов, которые взаимодействуют с API.

С другой стороны, если вы используете REST, будет рассматриваться просто предоставление RESTful URI.достаточно, чтобы удовлетворить ограничения веб-службы RESTful, имеющей унифицированный интерфейс.

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

В зависимости от того, какой язык вы используете, я предполагаю, что Java, вы можете использовать Restlets или Spring 3.0 'S REST Framework, чтобы помочь вам создать веб-сервис RESTful.Эти инструменты действительно облегчают эту работу и помогают вам соответствовать 6 ограничениям веб-службы RESTful и соответствовать 4 ключевым целям .

ОБНОВЛЕНИЕ:

Предполагая, что у вас уже есть существующий объектно-ориентированный код, и если вы хотите представить этот код в качестве REST API, с помощью Spring 3.0 MVC создайте подкласс Controller, который обернет ваш существующийпакет:

Пример GET :

Ресурс: Javadocs для ObjectMapper Джексона POJO / JSON Marshaller

 // this is the wrapper around your existing Java packages.  
 @Controller
 public class UserController {

     protected static final DATA_TYPE = "json";

     // In REST, GET method is used to retrieve data with no side effects, 
         // meaning that no changes are made to the data on the server.
     @RequestMapping(value="/users/{username}", method=RequestMethod.GET)
     public void getUserData(@PathVariable("username") String userName, Model model) {

         // this is your existing class
         UserDataService userDataService = new UserDataService();

         // assume you have a class User, and getUserDetails gives you that POJO object.
         User user = userDataService.getUserDetails(username);


         // marshal the User object to JSON, using Jackson, and write as output in response
         ObjectMapper mapper = new ObjectMapper();
         mapper.writeValue(response.getWriter(), user);

     }
 }

 // assume you have an existing POJO class called User
 class User implements Serializable {

     String username;
     String age;
     String birthday;
     String mood;

     String getMood() { return this.mood; }
     String getBirthday() { return this.birthday; }
     String getAge() { return this.age; }
     String getUsername() { return this.username; }

     String setMood(String mood) { this.mood = mood; }
     String setBirthday(String birthday) { this.birthday = birthday; }
     String setAge(String age) { this.age = age; }
     String setUsername(String username) { this.username = username; }
}

Запрос :

http://api.example.com:8080/users/jmort253/

Ответ:

{ 
    "username":"jmort253",
    "mood":"good",
    "age":"not too old and not too young",
    "birthday","Jan 1, 1900"
}

XML вместо JSON :

Основное различие между возвратом XML и возвращением JSON заключается в использовании маршаллера.Используя javax.xml.bind.annotations, вы можете размещать аннотации в классе POJO, чтобы маршаллер мог преобразовать его в XML, освобождая вас от необходимости вручную кодировать XML вручную:

Использование javax.xml.bind.annotations для преобразования объектов Java в XML и XSD .Этот ресурс также объясняет, как сгенерировать XML-схему, если вы считаете это обязательным требованием к вашей веб-службе REST.

 @XmlRootElement
 class User implements Serializable {

     String username;
     String age;
     String birthday;
     String mood;

     String getMood() { return this.mood; }
     String getBirthday() { return this.birthday; }
     String getAge() { return this.age; }
     String getUsername() { return this.username; }

     String setMood(String mood) { this.mood = mood; }
     String setBirthday(String birthday) { this.birthday = birthday; }
     String setAge(String age) { this.age = age; }
     String setUsername(String username) { this.username = username; }
}

Вместо того, чтобы использовать класс ObjectMapper API-интерфейса Джексона для преобразования класса POJO в JSON, используйтепакет javax.xml.bind.annotations вместо ObjectMapper:

JAXBContext context = JAXBContext.newInstance(User.class);
Marshaller marshaller = context.createMarshaller();

// pretty print XML
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
marshaller.marshal(user, System.out);

Помимо других ресурсов, в этой статье есть несколько примеров, в которых JAXB используется для десериализации ArrayList объектов POJO в XML.

Последнее предложение при работе с оболочками веб-службы REST - установить для всех уровней ведения журнала значение "ALL" или "DEBUG".Я считаю, что это помогает мне легче определить причину любых проблем, с которыми я сталкиваюсь при настройке веб-службы.Сами библиотеки будут выводить полезные сообщения отладки, которые помогут вам решить проблемы конфигурации, такие как отсутствующие зависимости, отсутствующие аннотации и другие проблемы, с которыми вы, вероятно, столкнетесь при работе с процессом преобразования в XML / JSON или при настройке Spring 3.0.

Как только вы настроите унифицированные интерфейсы, и вы сможете делать запросы GET и получать ответы, вы можете затем установить уровни ведения журнала на прежние уровни INFO или WARN.

1 голос
/ 31 января 2011

Прежде всего, я бы колебался, прежде чем выставлять существующий API в качестве веб-службы один на один.Был ли существующий API написан для доступа по сети?Если нет, то, вероятно, он не был разработан с учетом сетевых ограничений.

Это может включать вызовы методов, которые будут включать большее количество небольших операций - такого рода, который ничего не стоит при использовании в одном процессе.По сети каждый вызов имеет связанную задержку, которая намного больше, чем издержки на вызов метода в том же процессе.

Вместо этого я разработал бы сервис, отвечающий функциональным требованиям API.Скорее всего, служба должна иметь меньшее количество операций, которые выполняют больше работы на одну операцию, тем самым сводя к минимуму издержки, связанные с сетевым трафиком.Скорее всего, сервис будет реализован путем вызова API (при условии, что он написан для обработки многопоточных сред, таких как сервис).

В терминах WSDL используемый вами инструментарий можеточень хорошо построить WSDL для вас.Я знаю, что WCF в .NET делает это, и я сделал то же самое, используя IBM Rational Web Developer, поэтому я знаю, что мир Java может делать то же самое.

В противном случае, на самом деле это не так сложнонаписать WSDL и соответствующую схему.В любом случае, они do должны быть предоставлены, чтобы ваши клиенты могли использовать эту услугу.

Нет ничего плохого в использовании REST для этого, если ваш API может быть четко выражен как набороперации над ресурсами.В этом случае, да, предоставьте схему, чтобы вашим клиентам было проще обрабатывать XML.Я бы остерегался того, чтобы ваш API соответствовал модели REST, если она не может быть четко выражена как операции с ресурсами.

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