GEDOPLAN

Angular + OpenAPI Generator

Alle
openapi 1 1

In einem älteren Posting haben wir schon einmal einen Blick auf Swagger geworfen, eine charmante Möglichkeit aus den eigenen Rest-Schnittstellen eine technisch auswertbare OpenAPI Beschreibung zu generieren. Swagger bietet neben dieser Core-Möglichkeit noch eine ganze Reihe mehr, z.B. die Generierung von Client-Stubs. Das entsprechende Projekt ( Codegen ) wurde gefühlt eine ganze Zeitlang nicht aktiv verfolgt. Inzwischen lebt die Idee in einem Community getriebenem Projekt weiter: OpenAPI Generator. Werfen wir einen kurzen Blick auf die Verwendung im Zusammenspiel mit Angular.

openapi 1 1

Die Open API Spezifikation ist eine Standardbeschreibung für Schnittstellen die im JSON oder YAML Format Rest Schnittstellen (inklusive URL, Authentifizierung und Datenmodell) beschreibt. Eine Verwendungsmöglichksit ist die Generierung von Client-Code der die Entwicklung z.B. eines Anuglar-Clients erleichtert.

Der OpenApi Generator bietet hierbei unter anderem mit einem NPM-Tool welches ganz einfach per Kommandozeile installiert werden kann

npm install @openapitools/openapi-generator-cli -g

ein einfacher Aufruf zur Generierung von Angular-Sourcen könnte dann so aussehen:

openapi-generator generate -g typescript-angular -o src/app/api -i ./openapi.json

auf Basis der übergebenen API Spezifikation werden nun entsprechende Type-Script Sourcen generiert für

unsere Model-Klassen:

/**
 * The version of the OpenAPI document: 3.2
 *
 * NOTE: This class is auto generated by OpenAPI Generator 
(https://openapi-generator.tech).
 * Do not edit the class manually.
 */


export interface Project { 
    id?: number;
    projectId?: string;
    projectName?: string;
}

und eine zentrale Service-Klasse, die solche Methoden entsprechend unserer Resourcen generiert (unter Berücksichtigung von Pfadparametern und Rückgabewerten) (vereinfachte Darstellung):

public getAllProjects(limit?: number, first?: number): Observable<Project[]> {
    ...
        return this.httpClient.get<Array<Project>>(`${this.configuration.basePath}/resources/project`,
            {
                params: queryParameters,
                withCredentials: this.configuration.withCredentials,
                headers: headers,
                observe: observe,
                reportProgress: reportProgress
            }
        );
    }

Was nun lediglich noch fehlt für den Projektalltag ist die

  • Konfiguration der Base-URL, vorzugsweise über einen Provider, hier z.B. über die environmen.ts
@NgModule({
 ...
  providers: [
    {
      provide: BASE_PATH,
      useValue: environment.baseurl
    }
  ]
  ...
  • Login Credentials über HTTP-Interceptor hinzufügen
@Injectable({
  providedIn: 'root'
})
export class HttpJwtInterceptorService implements HttpInterceptor {
  constructor(private loginService: LoginService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = this.loginService.token;

    if (token) {
      req = req.clone({
        setHeaders: {
          Authorization: 'Bearer ' + this.loginService.token
        }
      });
    }
    return next.handle(req);
  }
}


// + Registrierung im Modul
@NgModule({
 ...
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      multi: true,
      useClass: HttpErrorInterceptorService
    }
  ]
  ...

Grundsätzlich eine sehr coole Sache, die uns viel Tipp-Arbeit spart. Im Hinterkopf sollte man aber immer behalten das wir damit unser Projekt auf zwei Generatoren stützen: 1) Swagger-Core um unsere OpenAPI zu generieren und 2) OpenAPI Generator um unsere Angular Artefakte erstellen zu lassen . Hier werden wir über kurz oder lang bei „komplexeren“ Schnittstellen an den Punkt kommen an dem einer der Generatoren nicht mehr das liefert was wir uns wünschen. Hier heißt es dann gegebenenfalls „händisch“ nach zu arbeiten. Eine Möglichkeit im Anuglar: generell mit einem Service-Delegate arbeiten: damit zentralisieren wir den Zugriff auf die generierten Teile unserer Anwendung und können hier auch zusätzliche Funktionalitäten implementieren ( z.B. „Caching“) und fachliche Gruppen („ProjektService“, „CustomerService“) ausprägen, auch wenn das wieder ein klein wenig Tipparbeit ist 😉

@Injectable({
  providedIn: 'root'
})
export class ProjectService {
  private projects: Project[];

  constructor(private service: DefaultService) {
  }

  getAll(limit?: number): Observable<Project[]> {
    if (!this.projects) {
      return this.service.getAllProjects(limit).pipe(tap(r => (this.projects = r)));
    } else {
      return from([this.projects]);
    }
  }
}

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Schulungen mit der selben Kategorie:

Blogkategorie: Alle
Es wurden keine Ergebnisse gefunden.

weitere Artikel

Kontakt

Brauchen Sie eine individuelle IT-Schulung, eine fundierte Beratung oder eine individuelle Softwareentwicklung? Dann sind Sie hier genau richtig!

Tim Neumann

Geschäftsleitung

GEDOPLAN GmbH
Stieghorster Straße 60
33605 Bielefeld

GEDOPLAN GmbH
Kantstraße 164
10623 Berlin

    Kontakt

    Tim Neumann

    Geschäftsleitung

    GEDOPLAN GmbH
    Stieghorster Straße 60
    33605 Bielefeld

    GEDOPLAN GmbH
    Kantstraße 164
    10623 Berlin

    Brauchen Sie eine individuelle IT-Schulung, eine fundierte Beratung oder eine individuelle Softwareentwicklung? Dann sind Sie hier genau richtig!