» » Панель управления услугами. Часть 2. На пути к фронтенду

 

Панель управления услугами. Часть 2. На пути к фронтенду

Автор: admin от 29-01-2018, 15:00, посмотрело: 327

Вступление. Еще немного про api.



Панель управления услугами. Часть 2. На пути к фронтенду



Итак, в прошлый раз мы остановились на описание процесса сборки api, с тех пор некоторые вещи успели измениться. А именно — Grunt была заменен на Gulp. Главная причина такой перестановки — скорость работы.

runSequence



gulp.task('client', (callback) => {
    runSequence(
        'client:indent',
        'client:concat',
        'client:replace',
        'client:validate',
        'client:toJson',
        'client:clean',
        callback
    );
});


То есть вместо стандартного объявления задачи для gulp, аргументом передается callback, в котором задачи выполняются по указанному порядке. В нашем случае порядок выполнения был важен только для 4 задач из 40, поэтому прирост в скорости по сравнению с Grunt ощутим.



Также, gulp позволил отказаться от coffeescript в пользу ES6. Код изменился минимально, но отпала необходимость при нечастых изменениях в конфигурации сборки api вспоминать как писать на coffeescript, так как нигде более он не использовался.

Пример части конфигураций для сравнения:



Gulp



gulp.task('admin:indent_misc', () => {
    return gulp.src(`${root}/projects.yml`)
        .pipe(indent({
            tabs: false,
            amount: 2
            }))
        .pipe(gulp.dest(`${interimDir}`))
});


Grunt



indent: 
  admin_misc:
    src: [
      '<%= admin_root %>/authorization.yml'
      '<%= admin_root %>/projects.yml'
    ]
    dest: '<%= admin_interim_dir %>/'
    options:
      style: 'space'
      size: 2
      change: 1 




Также, стоит упомянуть о небольших граблях, на которые нам удалось наступить.

Они заключались в следующем: после генерации файлов api и попытки запуска angular-приложение выводилась ошибка повторного экспорта ResourceService. Отправной точкой для поиска стал файл api/model/models.ts. Он содержит экспорты всех интерфейсов и сервисов, которые используются в дальнейшем.



Здесь следует добавить небольшое отступление и рассказать как swagger-codegen присваивает имена интерфейсам и сервисам.



[spoiler=Небольшое отступление]

Интерфейс

Исходя из шаблона интерфейса, если у свойства сущности указан тип object, то для него создается отдельные интерфейс, который именуется %Имя_сущностиИмя_свойства%.



Сервис

Исходя из шаблона сервиса имя сервиса состоит из имени тега и слова Service, например, OrderService. Поэтому, если указать у пути в спецификации несколько тегов, то этот метод попадет в несколько сервисов. Такой подход позволяет в одном случае импортировать только необходимый сервис и избежать импорта нескольких сервисов в другом.

[/spoiler]

Итак, в файле models.ts действительно присутствовало два экспорта ResourceService, один представлял сервиса для доступа к методам сущности resource, а второй — интерфейс для свойства service у сущности resource. Поэтому и возник такой конфликт. Решением стало переименование свойства.



От API к фронтенду.



Панель управления услугами. Часть 2. На пути к фронтенду



Как я уже говорил, спецификация swagger позволяет сформировать необходимые файлы работы с api как для бекенда, так и для фронтенда. В нашем случае, генерация кода api для Angular2 выполняется с помощью простой команды:



java -jar ./swagger-codegen-cli.jar generate  
-i client_swagger.json 
-l typescript-angular 
-o ../src/app/api 
-c ./typescript_config.json


Разбор параметров:




  • java -jar ./swagger-codegen-cli.jar generate — запуск jar-файла swagger-codegen

  • -i client_swagger.json – файл спецификации, полученный в итоге работы Gulp

  • -l typescript-angular – язык, для которого выполняется генерация кода

  • -o ../src/app/api — целевая директория для файлов api

  • -c ./typescript_config.json – дополнительная конфигурация (для устранения проблема именования переменных, о которой я рассказывал в первой части)



Учитывая, что количество языков, а соответственно шаблонов и кода для генерации, огромно, периодически в голове появляется мысль пересобрать codegen только под наши нужды и оставить только Typescript-Angular. Тем более, сами разработчики предоставляют инструкции по добавлению собственных шаблонов.



Таким нехитрым образом мы получаем все необходимые модули, интерфейсы, классы и сервисы для работы с api.

Пример одного из интерфейсов, полученных с помощью codegen:



[spoiler=Входной файл спецификации service_definition.yaml]
Service:
  type: object
  required:
    - id
  properties:
    id:
      type: integer
      description: Unique service identifier
      format: 'int32'
      readOnly: true
    date:
      type: string
      description: Registration date
      format: date
      readOnly: true
    start_date:
      type: string
      description: Start service date
      format: date
      readOnly: true
    expire_date:
      type: string
      description: End service date
      format: date
      readOnly: true
    status:
      type: string
      description: Service status
      enum:
        - 'empty'
        - 'allocated'
        - 'launched'
        - 'stalled'
        - 'stopped'
        - 'deallocated'
    is_primary:
      type: boolean
      description: Service primary state
    priority:
      type: integer
      description: Service priority
      format: 'int32'
      readOnly: true
    attributes:
      type: array
      description: Service attributes
      items:
        type: string
    primary_service:
      type: integer
      description: Unique service identifier
      format: 'int32'
      readOnly: true
      example: 138
    options:
      type: array
      items:
        type: string
    order:
      type: integer
      description: Unique order identifier
      format: 'int32'
      readOnly: true
    proposal:
      type: integer
      description: Unique proposal identifier
      format: 'int32'
      readOnly: true
    resources:
      type: array
      items:
        type: object
        properties:
          url:
            type: string
      description: Resources for this service
Services:
  type: array
  items:
    $ref: '#/definitions/Service'
[/spoiler]

[spoiler=На выходе получаем интерфейс, понятный angular’у]
import { ServiceOptions } from './serviceOptions';
import { ServiceOrder } from './serviceOrder';
import { ServicePrimaryService } from './servicePrimaryService';
import { ServiceProposal } from './serviceProposal';
import { ServiceResources } from './serviceResources';

/**
 * Service entry reflects fact of obtaining some resources within order (technical part). 
 In other hand service points to proposal that was used for ordering (commercial part).
 Service can be primary (ordered using tariff proposal) and non-primary (ordered using option proposal).
 */
export interface Service {
    /**
     * Record id
     */
    id: number;

    /**
     * Service order date
     */
    date?: string;

    /**
     * Service will only be launched after this date (if nonempty)
     */
    start_date?: string;

    /**
     * Service will be stopped after this date (if nonempty)
     */
    expire_date?: string;

    /**
     * Service current status. Meaning:
        * empty - initial status, not allocated
        * allocated - all option services and current service are allocated and ready to launch
        * launched - all option services and current one launched and works
        * stalled - service can be stalled in any time. Options also goes to the same status
        * stopped - service and option services terminates their activity but still stay allocated
        * deallocated - resources of service and option ones are released and service became piece of history
     */
    status?: number;

    /**
     * Whether this service is primary in its order. Otherwise it is option service
     */
    is_primary?: boolean;

    /**
     * Optional priority in order allocating process. The less number the earlier service will be allocated
     */
    priority?: number;

    primary_service?: ServicePrimaryService;

    order?: ServiceOrder;

    proposal?: ServiceProposal;

    /**
     * Comment for service
     */
    comment?: string;

    /**
     * Service's cost  (see also pay_type, pay_period, onetime_cost)
     */
    cost?: number;

    /**
     * Service's one time payment amount
     */
    onetime_cost?: number;

    /**
     * Bill amount calculation type depending on service consuming
     */
    pay_type?: Service.PayTypeEnum;

    /**
     * Service bill payment period
     */
    pay_period?: Service.PayPeriodEnum;

    options?: ServiceOptions;

    resources?: ServiceResources;

}
export namespace Service {
    export enum PayTypeEnum {
        Fixed = [leech=https://medium.com/@amcdnl/the-new-http-client-in-angular-4-3-754bd3ff83a8]тут[/leech]. Но, к сожалению, текущая стабильная версия codegen работает с HttpModule. Поэтому остаются подобные конструкции:</p>

<p><strong>HttpClientModule вернул был json по умолчанию:</strong></p>

[code].map((response: Response) => {
    if (response.status === 204) {
        return undefined;
    } else {
        return response.json() || {};
    }


Добавление заголовка для авторизации ложится на плечи HttpInterceptor:



if (this.configuration.accessToken) {
            let accessToken = typeof this.configuration.accessToken === 'function'
                ? this.configuration.accessToken()
                : this.configuration.accessToken;
            headers.set('Authorization', 'Bearer ' + accessToken);
        }


С нетерпением ждем обновления, а пока работаем с тем, что есть.



В следующей части я начну рассказ уже непосредственно про Angular и api буду касаться уже со стороны фронтенда.



Источник: Хабрахабр

Категория: Программирование

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *