Swashbuckle очень медленный для большой схемы

У меня есть база данных с более чем 90 таблицами, и все таблицы связаны друг с другом внешними ключами.

Когда я открываю страницу swagger для своего API, загрузка занимает более 2 минут. Причина, по-видимому, в том, что он генерирует Модель и Пример значения для каждого API. Из-за перекрестных ссылок практически каждый объект ссылается на любой другой объект (через рекурсивное транзитивное замыкание)!

Есть ли способ отключить или ограничить рекурсию, когда swagger генерирует Модель и Пример значения?

Например,

class A {
   int id;
   List<B> Blist;
}

class B {
   int id;
   List<C> Clist;
}

class C {
   int id;
   List<D> Dlist;
}

/// etc...

Если у меня есть API для GET /api/A, я не хочу перетаскивать все классы на страницу swagger Модель. Он слишком огромный!! Я только хочу втянуть А.


person John Henckel    schedule 27.04.2018    source источник
comment
Какая версия пользовательского интерфейса Swagger а Swashbuckle ты используешь? Можете ли вы попробовать загрузить свою спецификацию в последнюю версию пользовательского интерфейса Swagger и посмотреть, может быть, она работает лучше? Насколько велик ваш файл определения API (YAML/JSON)?   -  person Helen    schedule 28.04.2018
comment
Я думаю, используя Swashbuckle 5.6.0 и Swagger-UI 2.0.   -  person John Henckel    schedule 28.04.2018


Ответы (2)


Ответ на ваш вопрос короткий

Есть ли способ ограничить рекурсию, когда swagger генерирует модель и пример?

К сожалению нет!

В настоящее время такой опции нет. Но это возможно, и мы это обсуждаем:
https://github.com/swagger-api/swagger-ui/issues/4411
Добавьте туда комментарий и +1 к этой проблеме, сообщите команде, что это важно для вас.

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

Теперь ваша версия (2.x) больше не поддерживается, поэтому исправления не будет...
Пробовали ли вы Swagger-Net? Это моя вилка, и я использую последнюю версию пользовательского интерфейса.

person Helder Sepulveda    schedule 28.04.2018

Вот хак, который, кажется, «исправляет» это. Я добавил это в свой SwaggerConfig.cs

  c.MapType<MasterModel>(() => new Schema { type = "integer", format = "int32" });
  c.MapType<MasterLocationModel>(() => new Schema { type = "integer", format = "int32" });
  c.MapType<LocationModel>(() => new Schema { type = "integer", format = "int32" });

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

Возможно, есть способ сделать это лучше, используя SchemaFilter? Любая помощь будет оценена по достоинству.

ИЗМЕНИТЬ:

В конце концов, мы решили разделить наши классы, чтобы swagger не мог видеть ссылки более чем на один уровень в глубину. Например,

class A_Base {
   int id;
}

class A : A_Base {
   List<B_Base> Blist;
}

class B_Base {
   int id;
}

class B : B_Base {
   List<C_Base> Clist;
}

class C_Base {
   int id;
}

class C : C_Base {
   List<D_Base> Dlist;
}

и все API нашего контроллера используют типы A, B, C. Документ swagger будет углубляться только на один уровень для каждого. Рекурсия не выходит из-под контроля. Также это более правильно, потому что объекты, возвращаемые нашим API, обычно имеют нулевой или один уровень глубины.

person John Henckel    schedule 27.04.2018
comment
Этот ответ может иметь смысл для вас, но любой, кто читает ваш вопрос, задается вопросом, откуда берутся эти модели (MasterModel, MasterLocationModel, LocationModel)? - person Helder Sepulveda; 28.04.2018
comment
Также помните, что сгенерированная схема swagger используется не только пользовательским интерфейсом, существуют инструменты, которые используют ее и генерируют код для связи с вашим API (swagger.io/swagger-codegen), поэтому, если ваши модели неверны, сгенерированный код бесполезен. - person Helder Sepulveda; 29.04.2018
comment
Этот ответ очень помог мне в решении той же проблемы. Если у вас есть огромная модель данных, использование этого обходного пути может стать решением проблемы. Я могу предложить использовать эту технику для сущностей с циклическими ссылками. - person D. Pesc.; 06.11.2019