Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Где я написал, что обойтись? Но чем меньше языков, тем лучше.
Ага. И только у тебя получается, что три меньше двух.
НС>>>Нет. Потому что в 99% случаев аннотации вообще не нужны, а там где нужны — они крайне примитивны и в стандартном синтаксисе основного языка.
НС>·>Т.е. ты хочешь сказать, что можно наколбасить произвольный c# код и любому коду некий генератор может сгенерить юзабельную схему?
НС>Что значит произвольный? Схема генерится по вполне определенным классам контроллеров. И да, вполне можно обойтись без специальной разметки для OpenAPI. Можно и вообще без разметки.
Ок, уже теплее. Как эти классы контроллеров определяются? Как определяется что пойдёт в хедер, что в квери и т.п.? Ответ тут:
НС>Swashbuckle.
| Вот если это не EDSL, то я папа римский. |
| builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "An ASP.NET Core Web API for managing ToDo items",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Example Contact",
Url = new Uri("https://example.com/contact")
},
License = new OpenApiLicense
{
Name = "Example License",
Url = new Uri("https://example.com/license")
}
});
});
...
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Required]
[DefaultValue(false)]
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
|
| |
Домашнее задание — выяснить, что означает L в аббревиатуре EDSL и научиться считать до трёх.
НС>>>>>·>, имея все преимущества стротипизированного кода, а не писать всё с нуля.
НС>>>>>Что нужно писать с нуля и почему?
НС>>>·>Вот по твоему же заявлению: "писать клиентов нужно руками".
НС>>>И где здесь "с нуля"?
НС>·>А с чего?
НС>Со всего что позволяет язык.
Словоблудие.
НС>>>·>Ты говоришь, что модели разные. Генерация из одного описания даёт одну модель. Откуда разные?
НС>>>В том и проблема, что модель получается одна, хотя нужны разные.
НС>·>Разные модели чего? где? и для чего?
НС>Ответ на это я уже много раз давал. По кругу ходить не собираюсь.
Ну значит я не понял твой ответ. Ты там критиковал использование тех же POCO в ORM и в REST. Конечно, так делать не надо, и я такое никогда не предлагал. Точнее я ответ твой понял, но он был не в тему.
"Модели разные, а мы их пытаемся генератором преобразовать автоматически, получаем проблемы о которых я писал." — кто "мы" пытается модели преобразовывать генератором? Каким генератором? Зачем вообще преобразовывать модели генератором?
Может ты плохо представляешь как это работает? Вот конкретный пример:
1. пишем openapi спеку
2. Запускаем генератор, получаем "рыбу" — набор interface с методами и классы для dto-шек. Эту рыбу можно запаковать как отдельную либу (в принципе необязательно, код можно генерировать и по месту использования).
| нагенерится как-то так |
| @Generated
class UserDto {
private String id;
private String name;
String getName() {...};
void setName(String name){...};
}
@Generated
interface UserApi {
UserDto getUserByName(String name);
}
всё это дело будет густо обвешано аннотациями и кусками кода для всяких дефолтных значений, валидаций, маппингов на урлы-хедеры-етс. То что ты пишешь ручками в виде [DefaultValue(false)] и [HttpDelete("{id}")]. |
| |
3. На сервере подключаем эту либу и реализуем интерфейсы как классы контроллеров.
| пишем как-то так |
| class UserController implements UserApi {
@Override UserDto getUserByName(String name) {return new UserDto(...);}
}
httpServer.handle(new UserController(...));
|
| |
4. На клиенте подключаем эту же либу и используем эти же интерфейсы, чтобы дёргать сервер.
| пишем как-то так |
| var rest = new RestClient("http://server.address...");
var userApi = rest.getUserApi();
var userDto = userApi.getUserByName("vasya");
|
| |
5. всё.
Тебе нужно знать два языка — язык спеки openapi и язык программирования java. Никаких аннотаций писать не надо, изучать никаких библиотек не надо, максимум несколько опций генератора задать в настройках проекта.
Дальше по той же спеке можно генерить "рыбу" для javascript/typescript в браузере и т.п. А если захочется переписать кусочек сервера на scala/kotlin/etc — можно использовать соответствующий генератор для генерации более language-friendly рыбы.
Мода на code-first в java была лет 10-15 назад... Врочем и сейчас может использоваться в мелких проектах — запилить и забыть. А для дотнета наконец-то настал "2023й год на дворе, очнись"...
НС>>>·>Не очень понял. Что значит "генерировать для описания метаданных"? Пример, плз. Накой вообще при генерации нужно какое-то описание каких-то метаданных?
НС>>>Метаданные .NET ->
НС>·>Подробнее, что такое "Метаданные .NET"? Аннотации?
НС>https://learn.microsoft.com/en-us/dotnet/standard/assembly/contents
Вот эти метаданные и аннотации и должны описываться неким формальным языком, чтобы генератор мог работать и выдавать что-то вменяемое.
НС>>> генератор -> OpenAPI spec
НС>·>Ок, ну допустим. А дальше?
НС>Что дальше?
Ну сгенерили мы OpenAPI spec. Как и любой сгенерённый код она практически не человекочитаема, тулзы переваривать нормально не умеют... И накой? Что дальше с ней делать?
НС>·>"писать клиентов нужно руками"?
НС>Да, контракт клиента лучше описать руками. Но это не означает что нужно каждый раз все писать с нуля, генераторы это далеко не единственный способ реюза кода.
Почему лучше? Какие способы реюза ты предлагаешь?
НС>>>Потому что спецификация API это намного больше чем просто сериализация.
НС>·>Понятно, конечно. Но тут мы вроде обсуждение с dto-шек с 40 полями начали. И именно это покрывается сериализацией
НС>Нет конечно. Дтошки это прежде всего контракт, сериализация вторична.
Вторична да. Но в контексте дтошек в 40 полей это и есть — передать развесистый документ между системами — сериализовать по спеке, прогнать байтики, десериализовать. Что собственно сгенерированный из спек код и делает в основном.
НС> По одной и той же модели, к примеру, искаропки есть json и xml. В gRPC, разумеется, в силу его особенностей, приходится использовать protoc, но это именно его личная особенность.
Такая же личная особенность есть в thrift, avro, sbe, fix, asn.1 и т.п.
НС>А вот извив ума, по которому свойства в DTO оказывается нужны исключительно для сериализации — это тоже очень смелый подход к логике.
Согласен. Не извивайся так больше.