Giter Club home page Giter Club logo

atc-rest-api-generator's People

Contributors

allanhvam avatar christianhelle avatar cjakobsen avatar davidkallesen avatar egil avatar kimlundjohansen avatar lupusbytes avatar perkops avatar rickykaare avatar tommalow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

atc-rest-api-generator's Issues

ATC-API-GEN Client C# & TS

Kan vi bruge det der er eller skal vi bygge noget selv

Add the option for generating the model object in a separate project.

Code generation based on Swagger Petstore v3 OpenAPI specifications

The purpose of this issue is to align the code produced by the ATC REST API Generator to be as close as possible to what is defined in the OpenAPI specifications document in terms of how Swagger UI is rendered. A good way of testing this is to use the Swagger Petstore v3 example specification, which has become the standard specifications document to test against used when building code generators

Tasks:

Swagger UI differences

Here are some screenshots that indicate some pretty obvious differences between the original Swagger Petstore v3 rendered by https://petstore3.swagger.io (or https://editor.swagger.io) and the ATC generated code renders Swagger UI

swagger-petstore3

atc-swagger-petstore3

Implementing missing Info metadata

The OpenAPI Info object is represented by the Microsoft.OpenApi.Models.OpenApiInfo class and is used when configuring SwaggerGenOptions

Example usage:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddSwaggerGen(c =>
        {
            c.SwaggerDoc("1.0.5", new OpenApiInfo
            {
                Version = "1.0.5",
                Title = "Swagger Petstore - OpenAPI 3.0",
                Description = "Swagger Petstore - OpenAPI 3.0 (ASP.NET Core 3.1)",
                Contact = new OpenApiContact()
                {
                    Name = "Swagger Codegen Contributors",
                    Url = new Uri("https://github.com/swagger-api/swagger-codegen"),
                    Email = "[email protected]"
                },
                TermsOfService = new Uri("http://swagger.io/terms/")
            });
        });
}

The correct way of doing this is by implementing IConfigureOptions<SwaggerGenOptions> so that developers can have multiple implementations of IConfigureOptions<SwaggerGenOptions> whereas using the AddSwaggerGen extension method will prevent IConfigureOptions<SwaggerGenOptions> implementations from being called

XUnitTestHelper - AutoGeneratedCode Test

Create test which asserts that generated code has not changed.
Do this by reading in the yaml file - generate syntaxtrees - parse generated files

Compare files and fail unittest if something is changed
Added by perkops

Add support for role based security in ATC generator.

Tasks:

  • #137
    • Check if $ref can be used
  • Implement generator
    • Read schema
    • Validate security schema
    • Validate path schema
    • Validate role usage
    • Generate Authorize attribute
    • Demo project sample

Design

Setup in yaml file will be done using security schemes and the first type to support is OAuth2 with client id + client secret as authetication. Custom roles will be used to support access based on rights.

This can be done like shown below:

Definition of the security schema:

components:
  securitySchemes:

    oAuth2Sample:
      x-atc-azure-ad-application-roles:
          api.execute.all: 
            description:Access to all operations
            name: everything
          api.execute.read: 
            description: Access to smart charging operations.
            name: read

      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: 'https://login.microsoftonline.com/7b8ae8aa-f7d3-4bfe-a333-eb138ce54b98/oauth2/v2.0/token'
          refreshUrl: ''
          scopes:
            .default 
      description: OAuth2 using client id + client secret

Usage in a operation:

paths:
  '/items/{id}':
    put:
      summary: 'Updates an item'
      description: 'Updates an item'
      operationId: updateItem
      responses:
        '200':
          description: OK
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateItemRequest'
      parameters:
        - name: id
          in: path
          description: The id of the order
          required: true
          schema:
            type: string
            format: uuid
      security:
        - oAuth2Sample:
            - .default
        - x-atc-azure-ad-application-roles:
            - api.execute.read (can this be a $ref?)
            - api.execute.write

The generated code will affect the controller class(es) and will add an Authorize attribute to each method that is setup with security in its operation definition. The Roles property in the Authorize attribute maps to OAuth2 scopes and these are defined in the securiy scheme.

As the Roles property of the Authorize attribute treats multiple attributes on the same method as AND requirements it will be needed to have only 1 attribute per method to support OR and the roles will have to be comma separated. To make the code a bit nicer a static class with scope definitions are generated for each defined security schema.

Make sure Swagger UI shows the required roles per operation.

Validation:
ATC generator will validate the setup:

  • Unused role(s) (warning)
  • Undefined role(s) (error)
  • Roles not defined in OAuth2 schema (error)

The generated code could look something like this:

namespace Demo.Api.Generated.Security
{
    public static class OAuth2ClientCredentials
    {
        // Single roles
        public const string ApiExecuteAll = "api.execute.all";
        public const string ApiExecuteRead = "api.execute.read";

        // Combined roles
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Better readability for combined scopes.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Better readability for combined scopes.")]
        public const string ApiExecuteAll_ApiExecuteRead = ApiExecuteAll + "," + ApiExecuteRead;
    }
}
namespace Demo.Api.Generated.Endpoints
{
    /// <summary>
    /// Endpoint definitions.
    /// Area: Items.
    /// </summary>
    [ApiController]
    [Authorize]
    [Route("api/v1/items")]
    [GeneratedCode("ApiGenerator", "1.0.216.0")]
    public class ItemsController : ControllerBase
    {
        /// <summary>
        /// Description: Updates an item.
        /// Operation: UpdateItem.
        /// Area: Items.
        /// </summary>
        [HttpPut("{id}")]
        [Authorize(Roles = OAuth2ClientCredentials.ApiExecuteAll_ApiExecuteRead)]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        public Task<ActionResult> UpdateItemAsync(UpdateItemParameters parameters, [FromServices] IUpdateItemHandler handler, CancellationToken cancellationToken)
        {
            if (handler is null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            return InvokeUpdateItemAsync(parameters, handler, cancellationToken);
        }

        private static async Task<ActionResult> InvokeUpdateItemAsync(UpdateItemParameters parameters, IUpdateItemHandler handler, CancellationToken cancellationToken)
        {
            return await handler.ExecuteAsync(parameters, cancellationToken);
        }
    }
}

Unit tests of the generator code


ATC-API-GEN Unittesting, integration testing and smoketesting for all project-yamls fils in offucated mode

Improve unit test coverage. Might include some refactoring to make this easier.

Dem der tager denne opgave laver oplæg med Per og David så de selv kan arbejde videre.

Allow setting headers from handlers when spec'd for endpoints

In OpenAPI it is possible to specify headers in the response to a request. The ATC generator should enable us to add headers to the result returned from handlers related to endpoints that have headers specified in their responses.

Describe the solution you'd like

Right now the result types used with handlers follow a factory pattern, where the specified return codes are represented by methods.

I suggest we switch to a builder pattern, that allows us to pass multiple things in fluent style to the created result type. For example, with the following OpenAPI spec:

paths:
  /getFoo:
    get:
      summary: Return Foo
      responses:
        '200':
          description: OK
          headers:
            E-Tag:
              schema:
                type: string
              description: Foo E-Tag.
              required: true
            Secret-Foo-Age:
              schema:
                type: int
              description: The secret age of Foo
              required: false 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Foo'

The following result object builder could be generated:

Foo result = ...

return GetFooResult
          .OK()
          .WithContent(result)
          .WithETag("...")
          .WithSecretFooAge(42);

In the generated controller for the endpoint would then have to unpack the GetFooResult object and add any headers it contains to the response headers collection, perhaps as described here: https://www.jerriepelser.com/blog/paging-in-aspnet-webapi-http-headers/

ToString bug -> should be a count, if the property is a List<x>

Ensure generated ToString method that contains ref to a property of List<#> should be generated with ".Count" and have null check with "?" infront.

Example with 3 properties and the ToString-method:

    public class MyClass
    {
        public string Foo { get; set; }

        public List<string> Bar { get; set; }

        public List<string>? Baz { get; set; }

        public override string ToString()
        {
            return $"{nameof(Foo)}: {Foo}, {nameof(Bar)}.Count: {Bar.Count}, {nameof(Baz)}.Count: {Baz?.Count}";
        }
    }

Note: Also look at the project UseNull settings to generate the correct ToString.

Generator does not honor the "pattern" from a property

Describe the bug
Generator does not honor the "pattern" from a property, and hence does not produce a RegularExpression attribute on a parameter/request property.

Given this yaml:
image

The following is generated:

    [Required]
    [MinLength(2)]
    [MaxLength(2)]
    public string Alpha2Code { get; set; }

However, this should be generated:

    [Required]
    [MinLength(2)]
    [MaxLength(2)]
    [RegularExpression("^[A-Z]$")]
    public string Alpha2Code { get; set; }

Add support for controlling area name

Problem

The concept of an area in ATC generated code is used to control names of controllers, folders etc. This is today based solely on the root element of the api path. In some cases this is not ideal and this is a request to be able to control this.

An example is if multiple services are serving part of an api that share a common root element and it is actually a sub-element of the path that logically defines the area for each service.

Idea for solution

Be able to specify area name in the OpenApi file for each operation. Using the OpenApi spec for this will make it very clear how the area is linked to the generated code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.