Клиент Angular4 и Swagger

может кто поможет. Я пытаюсь использовать службу по умолчанию в своем компоненте для связи с REST API с бэкэнд-сервером python. Я пытаюсь использовать сгенерированный swagger-codegen клиент ng2 в angular. Сервер Python также создается с помощью swagger. Сервер работает,

import { Inject, Injectable, Optional } from '@angular/core';
import { Http, Headers, URLSearchParams } from '@angular/http';
import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http';
import { Response, ResponseContentType } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import '../rxjs-operators';

import { InlineResponseDefault } from '../model/inlineResponseDefault';

import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
import { Configuration } from '../configuration';
import { CustomQueryEncoderHelper } from '../encoder';


@Injectable()
export class DefaultService {

    protected basePath = 'http://127.0.0.1:8080/v1';
    public defaultHeaders = new Headers();
    public configuration = new Configuration();

    constructor(protected http: Http, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
        if (basePath) {
            this.basePath = basePath;
        }
        if (configuration) {
            this.configuration = configuration;
            this.basePath = basePath || configuration.basePath || this.basePath;
        }
    }

    /**
     * @param consumes string[] mime-types
     * @return true: consumes contains 'multipart/form-data', false: otherwise
     */
    private canConsumeForm(consumes: string[]): boolean {
        const form = 'multipart/form-data';
        for (let consume of consumes) {
            if (form === consume) {
                return true;
            }
        }
        return false;
    }


    public isJsonMime(mime: string): boolean {
        const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
        return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
    }

    /**
     * Abort the programm in the project identified by UUID
     * @param UUID The UUID
     */
    public abortProject(UUID: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.abortProjectWithHttpInfo(UUID, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * delete a single file at a specified path
     * @param UUID The UUID
     * @param path The path where to upload.
     */
    public deleteFile(UUID: string, path: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.deleteFileWithHttpInfo(UUID, path, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * Testing the connection
     */
    public ping(extraHttpRequestParams?: RequestOptionsArgs): Observable<string> {
        return this.pingWithHttpInfo(extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

Мой app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { DefaultService } from './rest/api/default.service';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [DefaultService],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

Я пытаюсь внедрить default.service в свой конструктор, и после этого браузер выдает сообщение ERROR NO PROVIDER FOR HTTP Injection error..... Я совершенно новичок в ng и ts :-(. После этого я определяю функция getPing для консоли протоколирует ответ сервера.

import { Component, OnInit } from '@angular/core';
import { InlineResponseDefault } from '../app/rest';
import { HttpClient, } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Response } from '@angular/http';
import { DefaultService } from './rest/api/default.service';
import { HttpClientModule } from '@angular/common/http';



@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})


export class AppComponent {
  title = 'app';


  constructor(private defaultService: DefaultService, public http: HttpClient) {

  }

  getPing() {
    console.log(this.defaultService.ping);
      }

}

person PaddyS    schedule 01.11.2017    source источник


Ответы (3)


У вас есть Http в одном месте и HttpClient в другом. Я настоятельно рекомендую прочитать документацию. Я предполагаю, что вы собираетесь использовать HttpClient, но если вы хотите вместо этого использовать Http, обратитесь к этому другая документация.

В default.service.ts обновите свой конструктор, чтобы использовать HttpClient:

constructor(protected http: HttpClient, ... other params ...)

В app.component.ts:

  • удалите параметр конструктора HttpClient:

    constructor(private defaultService: DefaultService) {}
    
  • обновите свой метод getPing(), чтобы он фактически вызывал метод ping() в сервисе по умолчанию:

    console.log(this.defaultService.ping()); 
    

    Без () он возвращает ссылку на функцию, а не вызывает функцию.

  • удалите импорт для HttpClientModule. Это нужно только в файле app.module.ts.

Ваш app.module.ts в порядке.

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

Как я уже говорил, это для HttpClient. Если вы хотите использовать Http, вам нужно вместо этого использовать HttpModule. Обратитесь к документации, на которую я ссылался выше, но рекомендуется использовать HttpClient.

person Roddy of the Frozen Peas    schedule 01.11.2017
comment
Спасибо, я исправил это. Вы говорите, что целой кучи методов не существует... Какие методы? Я думал, что могу вызвать функцию из моего клиента чванства, и он пингует сервер? Можете ли вы порекомендовать источник, где я могу больше узнать об angular4 и реализации клиента? - person PaddyS; 01.11.2017
comment
@PaddyS Неопределенные методы, подобные этому: this.abortProjectWithHttpInfo(...). Ключевое слово this указывает, что это метод класса, но DefaultService не имеет объявленного метода с именем abortProjectWithHttpInfo. Если это на самом деле метод в вашем API, вам нужно будет вызвать что-то вроде this.http.post("http://example.com/api/abortProjectWithHttpInfo",...). - person Roddy of the Frozen Peas; 01.11.2017
comment
Замороженные Спасибо за вашу помощь. Я публикую весь файл default.service в комментарии ниже с некоторым текстом. - person PaddyS; 01.11.2017
comment
@PaddyS Вы должны создать новый вопрос, если у вас есть дополнительные проблемы. StackOverflow следует модели вопросов и ответов, а не модели потоков с множеством ответов, поэтому нам нравится сохранять одну концепцию (или вопрос/ответ) для каждой темы. - person Roddy of the Frozen Peas; 01.11.2017

Проблема в том, что в app.module.ts вы импортируете HttpClientModule из @angular/common/http, а в своей службе вы пытаетесь внедрить HttpClient из @angular/http . Это версия, отличная от версии HTTP-клиента, и @angular/common/http является последней.

Измените свой сервис на:

import { HttpClient } from '@angular/common/http';
//
@Injectable()
export class DefaultService {
  constructor(protected http: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
person Christian Benseler    schedule 01.11.2017

@Roddy of the Frozen, вот и весь мой default.service.ts. Вы говорите, что если у меня есть эти методы, мне нужно вызвать this.http.post("http://example.com/api/abortProjectWithHttpI‌​nfo",...), но я подумал, что если я пропингую сервер, я смогу использовать ping из моего default.service. Я просто понимаю, что мое угловое приложение в браузере пусто. HTML не будет отображаться.... это расстраивает.

import { Inject, Injectable, Optional } from '@angular/core';
import { Http, Headers, URLSearchParams } from '@angular/http';
import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http';
import { Response, ResponseContentType } from '@angular/http';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import '../rxjs-operators';

import { InlineResponseDefault } from '../model/inlineResponseDefault';

import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
import { Configuration } from '../configuration';
import { CustomQueryEncoderHelper } from '../encoder';


@Injectable()
export class DefaultService {

    protected basePath = 'http://127.0.0.1:8080/v1';
    public defaultHeaders = new Headers();
    public configuration = new Configuration();

    constructor(protected http: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
        if (basePath) {
            this.basePath = basePath;
        }
        if (configuration) {
            this.configuration = configuration;
            this.basePath = basePath || configuration.basePath || this.basePath;
        }
    }

    /**
     * @param consumes string[] mime-types
     * @return true: consumes contains 'multipart/form-data', false: otherwise
     */
    private canConsumeForm(consumes: string[]): boolean {
        const form = 'multipart/form-data';
        for (let consume of consumes) {
            if (form === consume) {
                return true;
            }
        }
        return false;
    }


    public isJsonMime(mime: string): boolean {
        const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
        return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
    }

    /**
     * Abort the programm in the project identified by UUID
     * @param UUID The UUID
     */
    public abortProject(UUID: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.abortProjectWithHttpInfo(UUID, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * delete a single file at a specified path
     * @param UUID The UUID
     * @param path The path where to upload.
     */
    public deleteFile(UUID: string, path: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.deleteFileWithHttpInfo(UUID, path, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * Testing the connection
     */
    public ping(extraHttpRequestParams?: RequestOptionsArgs): Observable<string> {
        return this.pingWithHttpInfo(extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * Run the programm in the project identified by UUID
     * @param UUID The UUID
     */
    public runProject(UUID: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.runProjectWithHttpInfo(UUID, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }

    /**
     * Send a single file to the server
     * @param UUID The UUID
     * @param path The path where to upload.
     * @param file The single file to upload.
     */
    public sendFile(UUID: string, path: string, file: Blob, extraHttpRequestParams?: RequestOptionsArgs): Observable<{}> {
        return this.sendFileWithHttpInfo(UUID, path, file, extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
                    return response.json() || {};
                }
            });
    }


    /**
     * 
     * Abort the programm in the project identified by UUID
     * @param UUID The UUID
     */
    public abortProjectWithHttpInfo(UUID: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {
        if (UUID === null || UUID === undefined) {
            throw new Error('Required parameter UUID was null or undefined when calling abortProject.');
        }

        let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845

        // to determine the Content-Type header
        let consumes: string[] = [
            'application/x-www-form-urlencoded'
        ];
        let canConsumeForm = this.canConsumeForm(consumes);
        let useForm = false;
        let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
          set(param: string, value: any): void;
        };
        if (UUID !== undefined) {
            formParams.set('UUID', <any>UUID);
        }

        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: RequestMethod.Post,
            headers: headers,
            body: formParams.toString(),
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}/abort`, requestOptions);
    }

    /**
     * 
     * delete a single file at a specified path
     * @param UUID The UUID
     * @param path The path where to upload.
     */
    public deleteFileWithHttpInfo(UUID: string, path: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {
        if (UUID === null || UUID === undefined) {
            throw new Error('Required parameter UUID was null or undefined when calling deleteFile.');
        }
        if (path === null || path === undefined) {
            throw new Error('Required parameter path was null or undefined when calling deleteFile.');
        }

        let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845

        // to determine the Content-Type header
        let consumes: string[] = [
            'multipart/form-data'
        ];
        let canConsumeForm = this.canConsumeForm(consumes);
        let useForm = false;
        let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
          set(param: string, value: any): void;
        };
        if (UUID !== undefined) {
            formParams.set('UUID', <any>UUID);
        }
        if (path !== undefined) {
            formParams.set('path', <any>path);
        }

        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: RequestMethod.Delete,
            headers: headers,
            body: formParams.toString(),
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}/delete`, requestOptions);
    }

    /**
     * 
     * Testing the connection
     */
    public pingWithHttpInfo(extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {

        let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845

        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: RequestMethod.Get,
            headers: headers,
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}/ping`, requestOptions);
    }

    /**
     * 
     * Run the programm in the project identified by UUID
     * @param UUID The UUID
     */
    public runProjectWithHttpInfo(UUID: string, extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {
        if (UUID === null || UUID === undefined) {
            throw new Error('Required parameter UUID was null or undefined when calling runProject.');
        }

        let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845

        // to determine the Content-Type header
        let consumes: string[] = [
            'application/x-www-form-urlencoded'
        ];
        let canConsumeForm = this.canConsumeForm(consumes);
        let useForm = false;
        let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
          set(param: string, value: any): void;
        };
        if (UUID !== undefined) {
            formParams.set('UUID', <any>UUID);
        }

        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: RequestMethod.Post,
            headers: headers,
            body: formParams.toString(),
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}/run`, requestOptions);
    }

    /**
     * 
     * Send a single file to the server
     * @param UUID The UUID
     * @param path The path where to upload.
     * @param file The single file to upload.
     */
    public sendFileWithHttpInfo(UUID: string, path: string, file: Blob, extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {
        if (UUID === null || UUID === undefined) {
            throw new Error('Required parameter UUID was null or undefined when calling sendFile.');
        }
        if (path === null || path === undefined) {
            throw new Error('Required parameter path was null or undefined when calling sendFile.');
        }
        if (file === null || file === undefined) {
            throw new Error('Required parameter file was null or undefined when calling sendFile.');
        }

        let headers = new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845

        // to determine the Content-Type header
        let consumes: string[] = [
            'multipart/form-data'
        ];
        let canConsumeForm = this.canConsumeForm(consumes);
        let useForm = false;
        useForm = canConsumeForm;
        let formParams = new (useForm ? FormData : URLSearchParams as any)() as {
          set(param: string, value: any): void;
        };
        if (UUID !== undefined) {
            formParams.set('UUID', <any>UUID);
        }
        if (path !== undefined) {
            formParams.set('path', <any>path);
        }
        if (file !== undefined) {
            formParams.set('file', <any>file);
        }

        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: RequestMethod.Post,
            headers: headers,
            body: formParams.toString(),
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}/files`, requestOptions);
    }

}
person PaddyS    schedule 01.11.2017