Рубрики
Без рубрики

Апи-беспрепятственный прототипирование с угловатым

Начните прототипирование с минимальными изменениями в вашем приложении во время интеграции с Angular … Tagged с помощью Angular, TypeScript, JavaScript, WebDev.

Запустите прототипирование с минимальными изменениями в вашем приложении во время интеграции с угловальными инъекциями

Эта статья была первоначально опубликована на Остатки по ДЖАНКАРЛО ПУМПРИСКО

Я один из тех разработчиков, который обычно не могущественен, когда менеджер продуктов представляет функции нового продукта, над которыми я наконец -то может начать работать.

После планирования спринта я задаю страшный вопрос:

… и ответ часто негатив. Иногда ваши коллеги по бэкэнд более активны с другими вещами и не могут обеспечить даже фиктивную конечную точку. Нет, хотя, хотя!

При условии, что у вас есть жизнеспособный интерфейс DTO, с которым соглашается ваш коллега Вы можете начать создание прототипа новых функций с минимальными изменениями в вашем приложении во время интеграции с реальными конечными точками API.

Чтобы минимизировать изменения, необходимые во время интеграции, мы будем использовать силу Инъекции Angular и будет работать на обоих клиентах API одновременно:

  • Одним из них является высмеиваемая версия, которую мы будем называть Mockpriceapiservice

  • Другой – это фактическая услуга, которая будет поставляться с приложением, когда API будет готов к употреблению, который мы называем PriCeApiservice

  • Два класса будут реализовать интерфейс для установления контракта API между двумя

Быстрый совет: используйте Кусочек ( github ), чтобы поделиться, повторно использовать и обновить свои угловые компоненты по приложениям **. Бит -отслеживание и пучки многоразовые компоненты в ваших проектах и экспортируют их инкапсулированными с их зависимостями, компиляторами и всем остальным. Затем компоненты могут быть установлены с помощью менеджеров пакетов и даже обновлены прямо из любого нового проекта. Попробуйте.

Еще раз (!), Я построю минимальное приложение для криптовалюты в прямом эфире, которое будет работать как с высмеиваемыми ценами, так и с фактическим обслуживанием, которое вытащит цены из coincap.

Если вы нетерпеливы или просто tldr; Вы можете увидеть конечный результат на Stackblitz!

Конечный результат

Интерфейс API

Прежде всего, мы хотим установить, какой API поделятся два класса. Итак, мы строим интерфейс под названием Apiservice

import { Observable } from 'rxjs';

export interface PriceApi {
  getPrice(currency: string): Observable;
  unsubscribe(): void;
}

Как видите, услуги, которые будут реализовать этот интерфейс, должны будут предоставить только два публичных метода:

  • один, чтобы подписаться на поток цен

  • другой, чтобы отписаться по потоку.

Макетный сервис

Давайте начнем с создания фиктивного сервиса. Как мы уже говорили, нам нужно только внедрить два метода для уважения контракта. Короче говоря, мы хотим сделать:

  • Получите поток случайных чисел (цены), и мы оставим это из набора базовых цен, которые мы используем в качестве ссылки, чтобы скрепить цифры к реальным

  • Отписаться сказал поток

Приложение, которое мы создадим, поддержит только 3 валюты: биткойн, Litecoin и Ethereum.

const BASE_PRICES = {
  bitcoin: 11000,
  litecoin: 130,
  ethereum: 300
};

const randomize = (price: number) => {
  return (Math.random() * 2) + price;
};

@Injectable()
export class MockPriceApiService implements PriceApi {
  static latency = 250;
  private unsubsciptions$ = new Subject();

  public getPrice(currency: string): Observable {
    return timer(0, MockPriceApiService.latency).pipe(
      delay(1000),
      map(() => BASE_PRICES[currency]),
      map((price: number) => randomize(price)),
      map((price: number) => price.toFixed(5)),
      takeUntil(this.unsubsciptions$),
    )
  }

  public unsubscribe() {
    this.unsubsciptions$.next();
  }
}

Давайте объясним метод GetPrice:

  • Мы получаем параметр, называемый валютой, который представляет имя подписанного актива

  • Мы создаем таймер, который будет выделять событие каждые 250 мс

  • Мы откладываем излучаемое наблюдаемое на 1 секунду, чтобы имитировать реальную задержку сети

  • Мы принимаем base_price выбранной валюты и возвращаем число, которое рандомизируется при каждой эмиссии

  • Мы отписываем поток, когда субъект отказался от подписки $.

Настоящий сервис живых приходов

Как мы уже говорили, ваша команда может занять некоторое время, прежде чем вам будет предоставлен реальный API для реализации в вашем фронт-конце.

Однако, если ваша команда уже согласилась с интерфейсом, ничто не помешает вам заранее реализовать API и создать настоящий сервис наряду с фиктивным обслуживанием.

Чтобы заполнить наш пример, мы будем создавать реальную услугу и получить цены на услугу Coincap (еще раз!) И используем WebSocket для потоковой передачи цен на нашем клиенте.

Два публичных метода будут:

  • Создайте подключение к WebSocket и ценам потока, используя наблюдаемый, уважая контракт в интерфейсе

  • Закройте соединение, когда метод отписывает подпись. В результате поток цен прекратит излучать цены.

const WEB_SOCKET_ENDPOINT = 'wss://ws.coincap.io/prices/';

@Injectable()
export class PriceApiService implements PriceApi {
  private webSocket: WebSocket;

  public getPrice(currency: string): Observable {
    return this.connectToPriceStream(currency);
  }

  public unsubscribe() {
    this.webSocket.close();
  }

  private connectToPriceStream(asset: string): Observable {
    this.createConnection(asset);

    return new Observable(observer => {
      const webSocket = this.webSocket;

      webSocket.onmessage = (msg: MessageEvent) => {
        const data = JSON.parse(msg.data);
        observer.next(data[asset]);
      };

      return {
        unsubscribe(): void {
          webSocket.close();
        }
      };
    });
  }

  private createConnection(asset: string) {
    if (this.webSocket) {
      this.webSocket.close();
    }

    this.webSocket = new WebSocket(
      WEB_SOCKET_ENDPOINT + `?assets=${asset}`
    );
  }
}

Потребление данных службы

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

Давайте создадим компонент, который вводит PriCeApiservice:

  • Мы создаем свойство, которому мы назначаем поток, который мы называем цену $

  • Когда пользователь меняет криптовалюту, мы называем метод отписаться, если только валюта не была выбрана

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
  public price$: Observable;
  public currency$ = new BehaviorSubject(undefined);

  constructor(private api: PriceApiService) { }

  ngOnInit() {
    this.price$ = this.currency$.pipe(
      mergeMap((currency: string | undefined) => {
        return currency ? this.api.getPrice(currency) : of(undefined);
      })
    );
  }

  onCryptoSelected(currency: string) {
    if (this.currency$.value) {
      this.api.unsubscribe();
    }

    this.currency$.next(currency);
  }
}

А теперь на шаблоне:

  • Мы отображаем цену

  • Если цена все еще не определена, но валюта была выбрана, это означает, что подписка все еще продолжается: в результате мы показываем пользователю загрузочное сообщение

  • Если валюта не была выбрана, мы показываем пустое сообщение

{{ price$ | async }}
Awaiting for Price...
No Crypto Subscribed Yet

Службы переключения с использованием инъекции зависимостей

Вот волшебная часть. Благодаря инъекции зависимости Angular, мы можем предоставить, какую услугу мы хотим использовать, передав его тип и фактическому классу.

Как вы можете видеть ниже, мы обучаем DI:

  • Когда пользователь вводит PriCeApiservice

  • Используйте следующий класс: если Usemocks – это правда, используйте MockPriceApiservice, в противном случае используйте PriCeApiservice.

// in a real app could be environment.useMocks ?
const useMocks = true;

@NgModule({
  imports: [BrowserModule, CommonModule],
  declarations: [AppComponent, CryptoSelectorComponent],
  bootstrap: [AppComponent],
  providers: [
    {
      provide: PriceApiService,
      useClass: useMocks ? MockPriceApiService : PriceApiService
    }
  ]
})
export class AppModule { }

Конечно, пока ваши реальные конечные точки все еще строятся, ваш прототип будет

Как только ваша команда будет готова переключиться на реальные конечные точки, все, что вам нужно сделать, это переключить переменную среды на False (которая может быть установлена в вашем CI), и ваше приложение будет автоматически работать с реальными конечными точками!

Angular’s Di

Инъекция зависимости Angular очень мощная.

В дополнение к useclass, вы также можете использовать:

  • USEVALUE : Например, если вы хотите передать число, строку и т. Д.

  • Использование Factory : Например, Если вы хотите пройти функцию и использовать DI для введения зависимостей

И вы также можете использовать IncectionToken для прохождения разных значений, кроме классов.

Для получения полной ссылки о инъекции зависимости, я бы посоветовал вам прочитать полную документацию по адресу Angular.io Анкет

Результат

Вы можете увидеть конечный результат на Stackblitz!

Последние слова

Инъекция зависимостей является мощным инструментом и может использоваться различными полезными способами:

  • прототипирование

  • функции флагов

  • Перспективные услуги для тестов

  • Общая конфигурация

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

Если вам нужны какие -либо разъяснения, или если вы думаете, что что -то неясно или неправильно, пожалуйста, оставьте комментарий!

Если вам понравилась эта статья, следуйте за мной Середина или Твиттер для большего статьи об угловых, rxjs, typescript и многое другое!

Оригинал: “https://dev.to/gc_psk/api-less-prototyping-with-angular-5a0n”