swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
17.02k stars 6.03k forks source link

How to use swagger-codegen for Typescript-angular2 #3221

Closed rajeget closed 7 years ago

rajeget commented 8 years ago

Reference https://github.com/swagger-api/swagger-codegen/tree/master/samples/client/petstore/typescript-angular2/npm

These are ts file , how to compile and create a client ?

Please help

cburman01 commented 6 years ago

@scheler this only works in the 2.3.0-SNAPSHOT branch and - I guess - a correct authorization config in the yaml

securityDefinitions: Bearer: description: > jwt
type: apiKey name: Authorization in: header And the request definitions need this:

  security:
    - Bearer: []

Then the services will have this auto-generated code::

    // authentication (Bearer) required
    if (this.configuration.apiKeys["Authorization"]) {
        headers.set('Authorization', this.configuration.apiKeys["Authorization"]);
    }

@marcorinck Question about this: I believe I have followed your instructions, but the generated services do not have the code that adds the Authorization header like you said. I am using the 2.3.0 branch.

Generating typescript-angular from an aspnetcore api.

Middle ware is configured as so:

services.AddSwaggerGen(c =>
      {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
        {
          Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
          Name = "Authorization",
          In = "header",
          Type = "apiKey"

        });

Any ideas? Sorry to rez an old thread.

michalpirgl commented 6 years ago

Hi @cburman01

I have solved same task with AuthorizationHeaderOperationFilter

        public class AuthorizationHeaderOperationFilter : IOperationFilter
        {
            public void Apply(Operation operation, OperationFilterContext context)
            {
                IList<FilterDescriptor> filterDescriptors = context.ApiDescription.ActionDescriptor.FilterDescriptors;
                bool isAuthorized = filterDescriptors.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
                bool allowAnonymous = filterDescriptors.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);

                if (isAuthorized && !allowAnonymous)
                {
                    if (operation.Parameters == null)
                    {
                        operation.Parameters = new List<IParameter>();
                    }

                    operation.Parameters.Add(new NonBodyParameter
                    {
                        Required = true,
                        Default = "Bearer ",
                        In = "header",
                        Description = "Please insert JWT with Bearer into field",
                        Name = "Authorization",
                        Type = "apiKey"
                    });
                }
            }
        }

and in method ConfigureServices

// https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=netcore-cli
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {   Title = "...",
                                                Version = "...",
                                                Description = "..." });

                c.DescribeAllEnumsAsStrings();

                c.AddSecurityDefinition(
                    "Bearer",
                    new ApiKeyScheme() {
                        In = "header",
                        Description = "Please insert JWT with Bearer into field",
                        Name = "Authorization",
                        Type = "apiKey" });

                c.OperationFilter<AuthorizationHeaderOperationFilter>();
            });

Hope it helps.

vlados commented 6 years ago

Is it possible to create a page with the documentation for generating angular api client? Also does someone know how to generate a html documentation for that typescript client?

niuwenbo commented 6 years ago

@grEvenX

you can inject the configuration objekt anywhere in your application and can change the apiKeys property even during runtime. Like so:

class MyService {
   constructor(private configuration: Configuration, http: Http) {

   }

   login() {
        this.http.post("/login").subscribe((resp) => {
            this.configuration.apiKeys["Authorization"] = response.token;
        })
   }
}

You can change any configuration this way, but not the baseUrl property. I tried to argue on that earlier, but I don't think I got through.

i inject the Configuration to component and throw this error

Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[LoginPage -> Configuration]: StaticInjectorError(Platform: core)[LoginPage -> Configuration]: NullInjectorError: No provider for Configuration! Error: StaticInjectorError(AppModule)[LoginPage -> Configuration]: StaticInjectorError(Platform: core)[LoginPage -> Configuration]: NullInjectorError: No provider for Configuration! at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:1062) at resolveToken (core.js:1300) at tryResolveToken (core.js:1244) at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141) at resolveToken (core.js:1300) at tryResolveToken (core.js:1244) at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141) at resolveNgModuleDep (core.js:8369) at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9057) at resolveNgModuleDep (core.js:8369) at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:1062) at resolveToken (core.js:1300) at tryResolveToken (core.js:1244) at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141) at resolveToken (core.js:1300) at tryResolveToken (core.js:1244) at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1141) at resolveNgModuleDep (core.js:8369) at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9057) at resolveNgModuleDep (core.js:8369) at resolvePromise (zone.js:814) at resolvePromise (zone.js:771) at zone.js:873 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421) at Object.onInvokeTask (core.js:3811) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188) at drainMicroTaskQueue (zone.js:595)

this is my Configuration.ts file `export interface ConfigurationParameters { apiKeys?: {[ key: string ]: string}; username?: string; password?: string; accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean; }

export class Configuration { apiKeys?: {[ key: string ]: string}; username?: string; password?: string; accessToken?: string | (() => string); basePath?: string; withCredentials?: boolean;

constructor(configurationParameters: ConfigurationParameters = {}) {
    this.apiKeys = configurationParameters.apiKeys;
    this.username = configurationParameters.username;
    this.password = configurationParameters.password;
    this.accessToken = configurationParameters.accessToken;
    this.basePath = configurationParameters.basePath;
    this.withCredentials = configurationParameters.withCredentials;
}

/**
 * Select the correct content-type to use for a request.
 * Uses {@link Configuration#isJsonMime} to determine the correct content-type.
 * If no content type is found return the first found type if the contentTypes is not empty
 * @param {string[]} contentTypes - the array of content types that are available for selection
 * @returns {string} the selected content-type or <code>undefined</code> if no selection could be made.
 */
public selectHeaderContentType (contentTypes: string[]): string | undefined {
    if (contentTypes.length == 0) {
        return undefined;
    }

    let type = contentTypes.find(x => this.isJsonMime(x));
    if (type === undefined) {
        return contentTypes[0];
    }
    return type;
}

/**
 * Select the correct accept content-type to use for a request.
 * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type.
 * If no content type is found return the first found type if the contentTypes is not empty
 * @param {string[]} accepts - the array of content types that are available for selection.
 * @returns {string} the selected content-type or <code>undefined</code> if no selection could be made.
 */
public selectHeaderAccept(accepts: string[]): string | undefined {
    if (accepts.length == 0) {
        return undefined;
    }

    let type = accepts.find(x => this.isJsonMime(x));
    if (type === undefined) {
        return accepts[0];
    }
    return type;
}

/**
 * Check if the given MIME is a JSON MIME.
 * JSON MIME examples:
 *   application/json
 *   application/json; charset=UTF8
 *   APPLICATION/JSON
 *   application/vnd.company+json
 * @param {string} mime - MIME (Multipurpose Internet Mail Extensions)
 * @return {boolean} True if the given MIME is JSON, false otherwise.
 */
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');
}

} `