Code Monkey home page Code Monkey logo

openapi-delphi-generator's People

Contributors

wlandgraf avatar yonojoy avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openapi-delphi-generator's Issues

Server certificate error at request

The importer worked fine!

When i tried do call a basic function of the imported api the request rises a certificate error ; when i use an tidhttp component on the form and i call the function it works.
i don't know much about certificate managment, how cani fix the problem with the irestrequest calling?

EJsonExpectedValue exception on local .json file

Using a local file as input I get:
Exception: Cannot retrieve OpenApi version - Value expected but invalid character found at $ (EJsonExpectedValue)
The file was saved in Windows, and does not contain leading UTF-8 characters
If I change the file and insert 3 blanks at the start, it works fine.

Debugging in Delphi, in OpenApiGen.Main, function GetOpenApiVersion, I see the value of "Content" being
wagger":"2.0"...

proposed change to unit OpenApiGen.Main
function LoadContent(const Source: string; Options: TBuilderOptions): string;
var
Uri: IUri;
begin
if StartsText('http://', Source) or StartsText('https://', Source) then
begin
Result := LoadHttpContent(Source);
Uri := TUri.Create(Source);
if Options.DocumentUrl = '' then
Options.DocumentUrl := Uri.Scheme + '://' + Uri.Authority;
end
else
begin
Result := trim(TFile.ReadAllText(Source, TEncoding.UTF8));
if (Result <> '') and (Result[1] <> '{') then
Result := trim(TFile.ReadAllText(Source));
end;

end;

Stack overflow

I'm trying to use the generator on a large swagger-file 154 kB, swagger version 2.0 and I get

OpenApi Client Generator for Delphi version 1.1.1
Copyright (c) Landgraf.dev - all rights reserved.

EStackOverflow: Stack overflow

Suggestion: Add virtual `ExecuteRequest` function to `TCustomRestService`

At the moment following code is generated:

Request := CreateRequest(...);
Response := Request.Execute;
CheckError(Response);

I think it would be better, if the following code would be generated:

Request := CreateRequest(...);
Response := ExecuteRequest(Request);

With following default implementation of ExecuteRequest:

TCustomRestService.ExecuteRequest(ARequest: IRestRequest): IRestResponse;
begin
    Result := Request.Execute;
    CheckError(Result);        
end;

WHY?
I think it is cleaner to avoid the code duplication. But the most important reason is, that this kind of implementation allows for better error handling, eg:

TMyRestService.ExecuteRequest(ARequest: IRestRequest): IRestResponse;
begin
    try
        Result := inherited;
    except
        on E: Exception do
            if IsTokenExpiredException(E) then
            begin
                //Reset Client to refresh token
                Reset;
                //try to execute again
                Result := inherited;
            end
            else
              raise;
    end;
end;

Add ability for Logging

There should exist an lightweight option to add logging for requests and responses.

I would like to be able to add a logging class like this to do my logging for debugging purposes:

type
    TIOpenApiRestLogger = class(TInterfacedObject, IRestLogger)
    private
        FLogDir: string;
        function GetLogFileName(AMethod, AUrl: string; ALogId: string; APrefix: string = ''): string;
        function GetContentInfo(AMethod, AUrl: string): string;
    protected   //access via interface
        function LogRequest(AMethod: string; AUrl: string; ARequestBody: TStringStream): string;
        procedure LogResponse(AMethod: string; AUrl: string; ALogId: string; AResponse: IRestResponse);
    public
        constructor Create(ALogDir: string);
    end;

constructor TIOpenApiRestLogger.Create(ALogDir: string);
begin
    if ALogDir <> '' then
    begin
        ForceDirectories(ALogDir);
        FLogDir := MakePathStr(ALogDir);
    end;
end;

/// LogId is used to match request to response
function TIOpenApiRestLogger.GetLogFileName(AMethod, AUrl: string; ALogId: string; APrefix: string = ''): string;
var
    Path: string;
begin
    Path := ExtractUrlPath(AUrl);
    Result := FLogDir + APrefix + AMethod + '.'
      + StrToFileName(Path, REPLACE_SPACES_YES) + '.' + ALogId + '.txt';
end;

function TIOpenApiRestLogger.GetContentInfo(AMethod, AUrl: string): string;
begin
    Result := '---' + #13#10;        //YAML frontmatter format
    Result := Result + 'Method: ' + AMethod + #13#10;
    Result := Result + 'Url: ' + AUrl + #13#10;
end;


function TIOpenApiRestLogger.LogRequest(AMethod, AUrl: string; ARequestBody: TStringStream): string;
var
    ToLog: string;
begin
    Result := GuidToBase64(GenerateTGuid());
    if FLogDir <> '' then
    begin
        ToLog := GetContentInfo(AMethod, AUrl);
        ToLog := ToLog + '---' + #13#10;
        if Assigned(ARequestBody) then
          ToLog := ToLog + ARequestBody.DataString;

        StrToFile(GetLogFileName(AMethod, AUrl, Result, 'REQ.'), ToLog, TEncoding.UTF8);
    end;
end;

procedure TIOpenApiRestLogger.LogResponse(AMethod, AUrl, ALogId: string; AResponse: IRestResponse);
var
    ToLog: string;

    function HeaderInfo(AHeaderName: string): string;
    begin
        Result := '  ' + AHeaderName + ': ' + AResponse.GetHeader(AHeaderName) + #13#10;
    end;

begin
    Assert(Assigned(AResponse));
    //---
    if FLogDir <> '' then
    begin
        ToLog := GetContentInfo(AMethod, AUrl);
        ToLog := ToLog + 'StatusCode: ' + IntToStr(AResponse.StatusCode) + #13#10;
        ToLog := ToLog + 'Headers: ' + #13#10;
        ToLog := ToLog + HeaderInfo('Date');
        ToLog := ToLog + HeaderInfo('Content-Type');
        ToLog := ToLog + HeaderInfo('Content-Length');
        ToLog := ToLog + HeaderInfo('Connection');
        ToLog := ToLog + HeaderInfo('Vary');
        ToLog := ToLog + HeaderInfo('Allow');
        ToLog := ToLog + '---' + #13#10;
        ToLog := ToLog + AResponse.ContentAsString;

        StrToFile(GetLogFileName(AMethod, AUrl, ALogId, 'RESP.'), ToLog, TEncoding.UTF8);
    end;
end;

Support for null values

We have a server that delivers the following JSON (for TClient):

{
	"id": 6718,
	"first_name": "Hans",
	"last_name": "Bauer",
	"telephone": null,
	"email": null,
	"gender": null
}

If I read this into a TClient variable and then send this to the server again, this is translated to

{
	"id": 6718,
	"first_name": "Hans",
	"last_name": "Bauer",
	"telephone": "",
	"email": "",
	"gender": 0
}

which the server does not like: "0 is not a valid value for gender".

There are two solutions to this problem:

  1. Implement handling for null values
  2. Provide an option to treat null as not ...HasValue

While I think 1 is the correct solution, 2 can be implemented more easily by modifying OpenApiJson.pas, for example for USEDBX:

function TJsonWrapper.ObjContains(JObj: TJSONValue; const Name: string; out Value: TJSONValue): Boolean;
var
  Pair: TJSONPair;
begin
  Pair := TJSONObject(JObj).Get(Name);
  if Assigned(Pair) then
  begin
	Value := Pair.JsonValue;
	if Value.Null and FOptionTreatNullAsNotHasValue then
	  Value := nil;
  end
  else
	Value := nil;
end;

Solution 2 would result in the following JSON, which the server happily processes:

{
	"id": 6718,
	"first_name": "Hans",
	"last_name": "Bauer"
}

@wlandgraf What do you think?

Adding a GUI over the CLI

I'd like to add a simple FMX GUI for calling the command, do you think it could be interesting as a PULL REQUEST (with a "source-gui" folder) in the project or as a new repository ?

Pas file missing

Bcl.Code.MetaClasses missing
Bcl.Logging,
Bcl.Code.MetaClasses,
Bcl.Code.DelphiGenerator,
OpenAPI.Classes,
OpenAPI.Classes.Path,
OpenAPI.Classes.Operation,
OpenAPI.Classes.Parameter,
OpenAPI.Document,
OpenAPI.Types,
XData.JSchema.Classes,

Any more?

Can't import attached file; floating point error

Hello,

I try to import the attached json-file with:

OpenApiDelphiGen.exe -i:"t:\AB-API.json" -o:"T:" -n:HSAuftrag

I get the following error:

EConvertError: '#/components/requestBodies/UserWithPassword' is not a valid floating point value
AB-API.zip

What is the problem here?

Thanks

Stefan

DateTime values with more than 3 decimal places (parts of a second) will lead to an exception

We spotted this data in the wild:

"created_at":"2023-09-29T07:55:53.123860Z" 

This is not parsed, because TDateTimeFromJsonValue handles at maximum 3 decimal places, but ISO allows unlimited decimal places, see https://en.wikipedia.org/wiki/ISO_8601:

There is no limit on the number of decimal places for the decimal fraction. However, the number of
decimal places needs to be agreed to by the communicating parties.

Access violation with OpenAPI 3.0.0

I got an access violation exception when I tried with an OpenAPi 3.0 Specification(File and URL).
After attempting to compile using a trial version of TMS, I discovered that the issue lies in the line where TAnalyzer.Analyze(Document) is called.
I'm not sure but it could be a bug in the TMS library.

Error "Missing JSON schema type at..."

Hello,

I tried to import the OpenApi schema from Shipcloud, a parcel shipping provider. I got an error message running the importer:

EJSchemaReaderException: Missing JSON schema type at $.paths./addresses.post.responses.200.content.application/json.schema

The schema is attached. Any ideas whats going wrong ?

Best regards,

ht
shipcloud.json

Stack overflow for openapi 3.0 file

When I try to use the generator on the attached api file, I get a stack overflow:

.\OpenApiDelphiGen -i:".\testapi.json" -o:"D:\Delphi\test" -n:testapi -m:MultipleClientsFromFirstTagAndOperationId

OpenApi Client Generator for Delphi version 1.1.1
Copyright (c) Landgraf.dev - all rights reserved.

EStackOverflow: Stack overflow

The api file works fine in swagger and other openapi tools.

testapi.zip

F2069: Line too long (more than 1023 characters)

Importing https://developer.ebay.com/api-docs/master/sell/feed/openapi/3/sell_feed_v1_oas3.json

Has huge comment. Maybe can try and break them up?

Delphi 11.3

/// The value of the <strong>limit</strong> parameter submitted in the request, which is the maximum number of schedule templates to return per page, from the result set. A result set is the complete set of schedule templates returned by the method. <p> <span class="tablenote"><strong>Note:</strong> Though this parameter is not required to be submitted in the request, the parameter defaults to 10 if omitted.</span></p><p> <span class="tablenote"><strong>Note:</strong> If this is the last or only page of the result set, the page may contain fewer tasks than the <strong>limit</strong> value. To determine the number of pages in a result set, divide the total value (total number of tasks matching input criteria) by this limit value, and then round up to the next integer. For example, if the <strong>total</strong> value was <code>120</code> (120 total tasks) and the <strong>limit</strong> value was <code>50</code> (show 50 tasks per page), the total number of pages in the result set is three, so the seller would have to make three separate <strong>getScheduleTemplates</strong> calls to view all tasks matching the input criteria.</span></p>

XData Files are missing

the files openapi.v3.document and openapi.v3.json.serializer are missing. i have teh newest version of xdata installed.

where can i get them?

Json values are not correctly escaped (at least for XE4)

The JSON generated by TJsonWrapper.JsonValueToJson is not always correctly escaped.

For example

{"path":"C:\Test\"}

is generated, instead of

{"path":"C:\\Test\\"}

At least if Data.DBXJSON is used (XE4 support), this issue appears.

Handling of Double data type seems not to be correct

Given a OpenAPI parameter like this:

      {
        "name": "fee",
        "in": "query",
        "description": "",
        "required": false,
        "type": "number"
      }

the generated code uses the Double data type for Fee. This is than called in the following way:

Request.AddQueryParam('fee', Fee);

with

procedure AddQueryParam(const Name, Value: string);

This does not seem to be correct. The code should not rely on implicit conversion as this will use the system locale.
At least in XE4 this wont even compile.

A resolution would be to have an explicit conversion.

Missing JSON schema type 2

Hello,

I tried to import the OpenApi schema from qdrant, a vector database to be used on OpenAI embeddings. I got an error message running the importer:

EJSchemaReaderException: Missing JSON schema type at $.components.schemas.CollectionConfig.properties.quantization_config

OpenAPI Download

Thanks for any help.

Paths with multiple results ignored

Endpoints with multiple results are ignored and appropriate code is not generated. No (reason/warning) message is showed, it's very confusing.

Nice solution is used by nswag. For response 200 generate correct result (function result type) and typed exception for others (any exception with json object is welcomed).

------------ sample: json multiple responses ----------------

    "responses": {
      "200": {
        "description": "OK result - array of type 'Source' instances",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Sources"
            }
          }
        }
      },
      "default": {
        "description": "Processing error (unexpected)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Errors"
            }
          }
        }
      }
    }

------------- sample: nswag implementation -----------------

  ProcessResponse(client_, response_);

  var status_ = (int)response_.StatusCode;
  if (status_ == 200)
  {
      var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<Source>>(response_, headers_, cancellationToken).ConfigureAwait(false);
      if (objectResponse_.Object == null)
      {
          throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
      }
      return objectResponse_.Object;
  }
  else
  {
      var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<Error>>(response_, headers_, cancellationToken).ConfigureAwait(false);
      if (objectResponse_.Object == null)
      {
          throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
      }
      throw new ApiException<System.Collections.Generic.ICollection<Error>>("Processing error (unexpected)", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
  }

---------- the end -----------------------

Please clear up: May code generated by OpenAPI Client Generator for Delphi be used commercially?

To compile the code generated by this project the files in the Dist folder are necessary.
This project is licensed under the Apache 2.0 with Commons Clause License which forbids to sell the software generated by the code.
This means IMHO, that the generated code may not be use commercially.

Is this your intention?

If yes, you should place a clear statement on the project page to hint at this issue.
If no, you should license the files in the Dist folder under a more permissive license (eg. Apache 2.0 License).

No Overloaded Version Error

Hi, I encountered an error while compiling OpenApi250.bpl at the line FValues.AddPair(AName, AValue.Value);. The issue was resolved when I replaced it with FValues.AddPair(TJSONPair.Create(AName, AValue.Value.ToString));.

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.