В настоящее время я играю с моим сервисом отдыха jersey2. Для лучшего обзора данной услуги (описания, типы и т.д.) Я активно использую swagger (swagger-jersey2-jaxrs). Поэтому я могу генерировать описание моего сервиса (swagger.json), и я могу просматривать и исследовать их через swagger ui.
Теперь я нахожусь в том, что мне нужно создать несколько клиентов, чтобы использовать эти службы. Я пришел accrooss swagger codegen cli, который является хорошим инструментом для создания вашего клиента и многих разных языков (Java в моем случае). Я могу сгенерировать клиент api и используемую модель.
Здесь я столкнулся с первой проблемой. Услуги REST и описание swagger являются http basic auth protected. Я прочитал документацию которая дала мне некоторый намек на возможность использования базового auth. На этом этапе я должен упомянуть, что, с моей точки зрения, погашение очень плохое. В нем говорится:
-a, --auth добавляет заголовки авторизации при удалении определений swagger удаленно. Перейдите в строку заголовка с именем: header с запятой, разделяющей несколько значений.
Прежде всего, я хочу передать строку, как в заголовке http, но это не работает, и даже googling, как использовать базовый auth с swagger cli, не приводит к некоторому ясному answser. После многих попыток и ошибок я (я использую CLI 2.1.2), я, наконец, пришел в правильном формате, например:
java -jar swagger-codegen-cli-2.1.2.jar generate -a "Авторизация: Основной YWRtaW46YWRtaW4 =" -i http://localhost:8080/webproject/restapi/swagger.json -l java -o restclient
где YWRtaW46YWRtaW4 = - это закодированное значение base64 admin: admin в моем случае.
Пока все хорошо. Созданный Java-клиент должен также использовать базовый auth. Я взглянул на методы из ApiClient и нашел setUsername и setPassword. Я думал, что эти методы позволяют клиенту использовать базовый auth, но не повезло.
Итак, я более подробно рассмотрел созданные классы, особенно ApiClient и несколько сгенерированных классов ApiService. Я узнал, что setUsername и setPassword не действуют из-за следующего:
/**
* Helper method to set username for the first HTTP basic authentication.
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
где в то же время HashMap определяется как следующее:
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
Хеширование аутентификации становится неизменным, но почему? Что такое пурпус? Кроме того, в ApiClinet нет вспомогательных методов, которые генерируют необходимый объект auth, поэтому я сделал следующее:
1) закомментируйте аутентификации строк Collections.unmodifiableMap(аутентификации), чтобы хэш файл снова изменялся.
2) создать требуемый auth-объект вручную
HttpBasicAuth authentication = new HttpBasicAuth();
authentication.setUsername("admin");
authentication.setPassword("admin");
3) добавьте объект auth в hashmap аутентификации apiClients:
ApiClient apiClient = new ApiClient();
apiClient.setBasePath(basePath);
apiClient.getAuthentications().put("basic", authentication);
4) изменение метода invokeApi (ApiClient.java)
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
String authNames2[] = {"basic"};
updateParamsForAuth(authNames2, queryParams, headerParams);
//updateParamsForAuth(authNames, queryParams, headerParams);
...
Шаг 4 необходим, потому что ApiServices вызывают метод apiClient следующим образом:
String[] authNames = new String[] { };
String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
Другим возможным решением было бы определить ключ на основе hashmap аутентификации в каждом apiService, например:
String[] authNames = new String[] { "basic" };
После выполнения всех модификаций все работает так, как ожидалось, но я не могу думать, что это идея для автогенерированного клиента покоя. Поэтому мой вопрос: я пропустил какой-то момент или должен ли я думать о клиенте, создаваемом swagger (java в этом случае), о бета-решении, которое находится в разработке? Пожалуйста, поймите меня правильно, я думаю, что вся инфраструктура swagger (поддержка jersey2, openapi, swaggerui, codegen) - отличная вещь, и я ценю усилия разработчиков, но я хочу использовать право codegen, и я не думаю, что идея поэтому необходимо настроить созданный ApiClient и ApiServices таким образом.