Skip to content

Commit

Permalink
Correctly implemented TOpenAPIPathItem class
Browse files Browse the repository at this point in the history
Other small fixes
  • Loading branch information
paolo-rossi committed Jun 4, 2021
1 parent 22dbc74 commit 2115da5
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 38 deletions.
22 changes: 13 additions & 9 deletions Demos/OpenAPI/Demo.Form.Main.dfm
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ object frmMain: TfrmMain
TabOrder = 1
object panGeneral: TCategoryPanel
Top = 0
Height = 321
Height = 441
Caption = 'OpenAPI Document'
TabOrder = 0
object CategoryButtons1: TCategoryButtons
Left = 0
Top = 0
Width = 196
Height = 295
Height = 415
Align = alClient
ButtonFlow = cbfVertical
ButtonOptions = [boFullSize, boGradientFill, boShowCaptions, boUsePlusMinus]
Expand Down Expand Up @@ -93,41 +93,44 @@ object frmMain: TfrmMain
Collapsed = False
Items = <
item
Caption = 'Add Paths'
Action = actAddPaths
end
item
Caption = 'Add Security'
Action = actAddSecurity
end
item
end>
end>
RegularButtonColor = clWhite
SelectedButtonColor = 15132390
TabOrder = 0
ExplicitHeight = 295
end
end
object CategoryPanel1: TCategoryPanel
Top = 321
Height = 168
Top = 441
Height = 120
Caption = 'JSON Generation'
TabOrder = 1
ExplicitTop = 321
object CategoryButtons2: TCategoryButtons
Left = 0
Top = 0
Width = 196
Height = 142
Height = 94
Align = alClient
ButtonFlow = cbfVertical
Categories = <>
RegularButtonColor = clWhite
SelectedButtonColor = 15132390
TabOrder = 0
ExplicitHeight = 142
end
object catJSON: TCategoryButtons
Left = 0
Top = 0
Width = 196
Height = 142
Height = 94
Align = alClient
ButtonFlow = cbfVertical
ButtonOptions = [boFullSize, boGradientFill, boShowCaptions, boUsePlusMinus]
Expand All @@ -147,6 +150,7 @@ object frmMain: TfrmMain
RegularButtonColor = clWhite
SelectedButtonColor = 15132390
TabOrder = 1
ExplicitHeight = 142
end
end
end
Expand All @@ -163,7 +167,7 @@ object frmMain: TfrmMain
OnExecute = actAddServersExecute
end
object actAddPaths: TAction
Caption = 'Add Paths & Params'
Caption = 'Add Paths && Params'
OnExecute = actAddPathsExecute
end
object actAddSecurity: TAction
Expand Down
39 changes: 29 additions & 10 deletions Demos/OpenAPI/Demo.Form.Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ procedure TfrmMain.actAddInfoExecute(Sender: TObject);

procedure TfrmMain.actAddServersExecute(Sender: TObject);
begin
FDocument.Servers.Add(TOpenAPIServer.Create('https://api.mycompany.com/rest/app/', 'Production Server'));
FDocument.Servers.Add(TOpenAPIServer.Create('https://beta.mycompany.com/rest/app/', 'Beta Server API v2'));
FDocument.Servers.Add(TOpenAPIServer.Create('https://test.mycompany.com/rest/app/', 'Testing Server'));
FDocument.Servers.Add(TOpenAPIServer.Create('https://api.wirl.com/rest/app/', 'Production Server'));
FDocument.Servers.Add(TOpenAPIServer.Create('https://beta.wirl.com/rest/app/', 'Beta Server API v2'));
FDocument.Servers.Add(TOpenAPIServer.Create('https://test.wirl.com/rest/app/', 'Testing Server'));
end;

procedure TfrmMain.actAddPathsExecute(Sender: TObject);
Expand All @@ -105,14 +105,19 @@ procedure TfrmMain.actAddPathsExecute(Sender: TObject);
LParameter.Schema.Type_ := 'string';
LParameter.Schema.Enum.ValueFrom<TArray<string>>(['it', 'en', 'de', 'ch', 'fr']);

LParameter := LOperation.AddParameter('date', 'query');
LParameter.Description := 'Date';
LParameter.Schema.Type_ := 'string';
LParameter.Schema.Format := 'date-time';
LParameter.Schema.Enum.ValueFrom<TArray<string>>(['it', 'en', 'de', 'ch', 'fr']);
end;

procedure TfrmMain.actCompAddResponsesExecute(Sender: TObject);
var
LResponse: TOpenAPIResponse;
LMediaType: TOpenAPIMediaType;
begin
LResponse := FDocument.Components.AddResponse('200', 'Successful response');
LResponse := FDocument.Components.AddResponse('200', 'Successful Response');
LMediaType := LResponse.AddMediaType('application/json');
LMediaType.Schema.Reference.Ref := '#components/schemas/country';
end;
Expand All @@ -122,27 +127,39 @@ procedure TfrmMain.actCompAddSchemasExecute(Sender: TObject);
LSchema: TOpenAPISchema;
LProperty: TOpenAPISchema;
begin
LSchema := FDocument.Components.AddSchema('Category');
LSchema := FDocument.Components.AddSchema('Person');
LSchema.Type_ := 'object';

LProperty := LSchema.AddProperty('id');
LProperty.Title := 'ID Value';
LProperty.Description := 'AutoInc **ID** value';
LProperty.Type_ := 'integer';
LProperty.Format := 'int64';

LProperty := LSchema.AddProperty('name');
LProperty := LSchema.AddProperty('firstname');
LProperty.Type_ := 'string';

LProperty := LSchema.AddProperty('lastname');
LProperty.Type_ := 'string';

LProperty := LSchema.AddProperty('birthdate');
LProperty.Title := 'Birth Date';
LProperty.Description := 'Birth Date';
LProperty.Type_ := 'string';
LProperty.Format := 'date-time';
end;

procedure TfrmMain.actCompAddSecurityDefsExecute(Sender: TObject);
begin
FDocument.Components.AddSecurityApiKey('key_auth', 'Key Standard Authentication', 'X-ApiKey', tapikeylocation.Header);
FDocument.Components.AddSecurityHttp('basic_auth', 'Basic Authentication', 'Basic', '');
FDocument.Components.AddSecurityHttp('bearer_auth', 'Bearer Authentication', 'Bearer', 'Bearer');
FDocument.Components.AddSecurityHttp('jwt_auth', 'JWT (Bearer) Authentication', 'Bearer', 'JWT');
end;

procedure TfrmMain.actAddSecurityExecute(Sender: TObject);
begin
FDocument.AddSecurity('basic_auth', []);
FDocument.AddSecurity('bearer_auth', []);
FDocument.AddSecurity('jwt_auth', []);
end;

procedure TfrmMain.actCompAddParametersExecute(Sender: TObject);
Expand All @@ -157,12 +174,14 @@ procedure TfrmMain.actCompAddParametersExecute(Sender: TObject);

procedure TfrmMain.actJSONGenerateExecute(Sender: TObject);
begin
memoDocument.Lines.Text := TNeon.ObjectToJSONString(FDocument, TOpenAPISerializer.GetNeonConfig);
memoDocument.Lines.Text :=
TNeon.ObjectToJSONString(FDocument, TOpenAPISerializer.GetNeonConfig);
end;

procedure TfrmMain.actJSONReplaceExecute(Sender: TObject);
begin
memoDocument.Lines.Text := StringReplace(memoDocument.Lines.Text, '\/', '/', [rfReplaceAll]);
memoDocument.Lines.Text :=
StringReplace(memoDocument.Lines.Text, '\/', '/', [rfReplaceAll]);
end;

procedure TfrmMain.FormCreate(Sender: TObject);
Expand Down
103 changes: 84 additions & 19 deletions Source/OpenAPI.Models.pas
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ TOpenAPILicense = class(TOpenAPIModel)
/// <summary>
/// ExternalDocs object
/// </summary>
TOpenAPIExternalDocumentation = class
TOpenAPIExternalDocumentation = class(TOpenAPIModel)
private
FDescription: NullString;
FUrl: string;
Expand Down Expand Up @@ -814,7 +814,7 @@ TOpenAPIRequestBodyMap = class(TObjectDictionary<string, TOpenAPIRequestBody>)
/// <summary>
/// An object representing a Server Variable for server Url template substitution
/// </summary>
TOpenAPIServerVariable = class
TOpenAPIServerVariable = class(TOpenAPIModel)
private
FEnum: TArray<string>;
FDefault_: string;
Expand Down Expand Up @@ -845,7 +845,7 @@ TOpenAPIServerVariableMap = class(TObjectDictionary<string, TOpenAPIServerVari
/// <summary>
/// An object representing a Server
/// </summary>
TOpenAPIServer = class
TOpenAPIServer = class(TOpenAPIModel)
private
FDescription: NullString;
FVariables: TOpenAPIServerVariableMap;
Expand Down Expand Up @@ -1334,7 +1334,7 @@ TOpenAPIOperationMap = class (TObjectDictionary<TOperationType, TOpenAPIOperat
/// <summary>
/// The object provides metadata about the API
/// </summary>
TOpenAPIInfo = class
TOpenAPIInfo = class(TOpenAPIModel)
private
FContact: TOpenAPIContact;
FDescription: NullString;
Expand Down Expand Up @@ -1382,7 +1382,7 @@ TOpenAPIInfo = class
/// <summary>
/// Component Object.
/// </summary>
TOpenAPIComponents = class
TOpenAPIComponents = class(TOpenAPIModel)
private
FSchemas: TOpenAPISchemaMap;
FResponses: TOpenAPIResponseMap;
Expand Down Expand Up @@ -1468,15 +1468,23 @@ TOpenAPIComponents = class
end;

/// <summary>
/// An object representing a Server Variable for server Url template substitution
/// Path Item Object: to describe the operations available on a single path.
/// </summary>
TOpenAPIPathItem = class(TOpenAPIOperationMap)
TOpenAPIPathItem = class(TOpenAPIModel)
private
FSummary: NullString;
FDescription: NullString;
//FOperations: TOpenAPIOperationMap;
FServers: TOpenAPIServerMap;
FParameters: TOpenAPIParameterMap;
FGet: TOpenAPIOperation;
FPut: TOpenAPIOperation;
FHead: TOpenAPIOperation;
FPatch: TOpenAPIOperation;
FPost: TOpenAPIOperation;
FTrace: TOpenAPIOperation;
FDelete: TOpenAPIOperation;
FOptions: TOpenAPIOperation;
public
constructor Create;
destructor Destroy; override;
Expand All @@ -1496,10 +1504,52 @@ TOpenAPIPathItem = class(TOpenAPIOperationMap)
property Description: NullString read FDescription write FDescription;

/// <summary>
/// Gets the definition of operations on this path.
/// Get Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Get: TOpenAPIOperation read FGet write FGet;

/// <summary>
/// Put Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Put: TOpenAPIOperation read FPut write FPut;

/// <summary>
/// Post Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Post: TOpenAPIOperation read FPost write FPost;

/// <summary>
/// Delete Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Delete: TOpenAPIOperation read FDelete write FDelete;

/// <summary>
/// Options Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Options: TOpenAPIOperation read FOptions write FOptions;

/// <summary>
/// Head Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Head: TOpenAPIOperation read FHead write FHead;

/// <summary>
/// Patch Operation
/// </summary>
//[NeonInclude(IncludeIf.NotEmpty)]
//property Operations: TOpenAPIOperationMap read FOperations write FOperations;
[NeonInclude(IncludeIf.NotEmpty)]
property Patch: TOpenAPIOperation read FPatch write FPatch;

/// <summary>
/// Trace Operation
/// </summary>
[NeonInclude(IncludeIf.NotEmpty)]
property Trace: TOpenAPIOperation read FTrace write FTrace;

/// <summary>
/// An alternative server array to service all operations in this path.
Expand Down Expand Up @@ -1529,7 +1579,7 @@ TOpenAPIPathMap = class(TObjectDictionary<string, TOpenAPIPathItem>)
/// A document (or set of documents) that defines or describes an API. An Openapi
/// definition uses and conforms to the Openapi Specification
/// </summary>
TOpenAPIDocument = class
TOpenAPIDocument = class(TOpenAPIModel)
private
FInfo: TOpenAPIInfo;
FOpenapi: string;
Expand Down Expand Up @@ -1602,9 +1652,6 @@ TOpenAPIDocument = class

implementation

uses
Neon.Core.Utils;

{ TOpenAPIServer }

constructor TOpenAPIServer.Create;
Expand Down Expand Up @@ -1795,15 +1842,17 @@ constructor TOpenAPIParameterMap.Create;

function TOpenAPIDocument.AddPath(const AKeyName: string): TOpenAPIPathItem;
begin
if not AKeyName.StartsWith('/') then
raise EOpenAPIException.Create('A path MUST begin with a forward slash "/"');
Result := TOpenAPIPathItem.Create;
FPaths.Add(AKeyName, Result);
end;

procedure TOpenAPIDocument.AddSecurity(ASchemeName: string; AParams: TArray<string>);
var
s: TOpenAPISecurityScheme;
LScheme: TOpenAPISecurityScheme;
begin
if Assigned(FComponents) and FComponents.SecuritySchemes.TryGetValue(ASchemeName, s) then
if FComponents.SecuritySchemes.TryGetValue(ASchemeName, LScheme) then
FSecurity.Add(ASchemeName, AParams)
else
raise EOpenAPIException.CreateFmt('The scheme [%s] does not exists in securityDefinitions', [ASchemeName]);
Expand Down Expand Up @@ -1914,9 +1963,26 @@ constructor TOpenAPIMediaTypeMap.Create;
{ TOpenAPIPathItem }

function TOpenAPIPathItem.AddOperation(const AType: TOperationType): TOpenAPIOperation;
function GetOrCreate(var ASource: TOpenAPIOperation): TOpenAPIOperation;
begin
if not Assigned(ASource) then
ASource := TOpenAPIOperation.Create;
Result := ASource;
end;

begin
Result := TOpenAPIOperation.Create;
Self.Add(AType, Result);
case AType of
TOperationType.Get: Result := GetOrCreate(FGet);
TOperationType.Put: Result := GetOrCreate(FPut);
TOperationType.Post: Result := GetOrCreate(FPost);
TOperationType.Delete: Result := GetOrCreate(FDelete);
TOperationType.Options: Result := GetOrCreate(FOptions);
TOperationType.Head: Result := GetOrCreate(FHead);
TOperationType.Patch: Result := GetOrCreate(FPatch);
TOperationType.Trace: Result := GetOrCreate(FTrace);
else
raise EOpenAPIException.CreateFmt('Operation Type [%s] not supported', []);
end;
end;

function TOpenAPIPathItem.AddParameter(const AKeyName: string): TOpenAPIParameter;
Expand All @@ -1933,7 +1999,6 @@ function TOpenAPIPathItem.AddServer(const AKeyName: string): TOpenAPIServer;

constructor TOpenAPIPathItem.Create;
begin
inherited;
//FOperations := TOpenAPIOperationMap.Create;
FServers := TOpenAPIServerMap.Create;
FParameters := TOpenAPIParameterMap.Create;
Expand Down

0 comments on commit 2115da5

Please sign in to comment.