Re[28]: Догонит ли net java?
От: · Великобритания  
Дата: 13.12.22 22:19
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Где я написал, что обойтись? Но чем меньше языков, тем лучше.

Ага. И только у тебя получается, что три меньше двух.

НС>>>Нет. Потому что в 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 оказывается нужны исключительно для сериализации — это тоже очень смелый подход к логике.

Согласен. Не извивайся так больше.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.