2017-09-14 7 views
3

Je viens de commencer à expérimenter avec RAD Server. L'une des caractéristiques qui rendent l'investissement attrayant est la fonction d'auto-documentation de l'API, qui permettrait d'économiser beaucoup de travail en supportant les partenaires externes se connectant à nos interfaces REST, et évite le besoin de maintenir un document de spécification d'interface distinct. le développement.Comment créer une documentation YAML à l'aide des attributs de documentation EMS

J'ai suivi le tutoriel sur le wiki pour créer une première ressource EMS jusqu'au déploiement sur un serveur EMS de test. Cela fonctionne bien, sans accroc. Cependant, lorsque j'atteins le tutoriel custom API documentation, cela ne fonctionne tout simplement pas. J'ai regardé la publication de Stephen Ball au SWAGGER/YAML AND SELF DOCUMENTING RESTFUL API’S. Malheureusement, il utilise le projet RAD Studio EMS Sample, qui fonctionne parfaitement même pour moi. Mais la minute où j'essaie d'appliquer les mêmes attributs à mon propre package EMS, cela ne fonctionne pas.

Quand j'appelle htt: // localhost: 8080/api/apidoc.yaml le serveur renvoie:

{ 
    "error":"Error", 
    "description":"Error: No Responses defined for: get " 
} 

Le serveur de développement EMS a les entrées de journal correspondantes suivantes:

{"Request":{"Resource":"API","Endpoint":"GetAPIYAMLFormat","Method":"GET","User":"(blank)","Time":"2017/08/11 12:59:46 AM","Thread":1732}} 
{"Error":{"Type":"HTTP","Code":"500","Reason":"Error","Error":"","Description":"Error: No Responses defined for: get ","Thread":1732}} 

ici est un extrait de mon code issu du tutoriel:

unit Unit1; 

// EMS Resource Unit 

interface 

uses 
    System.SysUtils, System.Classes, System.JSON, 
    EMS.Services, EMS.ResourceAPI, 
    EMS.ResourceTypes, APIDocumentationEndPointObjectsDefinitions; 

type 
    [ResourceName('Test')] 
    [EndPointObjectsYAMLDefinitions(YAMLDefinitions)] 
    [EndPointObjectsJSONDefinitions(JSONDefinitions)] 

    {$METHODINFO ON} 
    TTestResource = class 
    published 
    // Declare the function 
    function MakeJSON(I: Integer): TJSONObject; //It takes an integer as a parameter and returns a JSON Object. 
    [EndPointRequestSummary('Items', 'Get items', 'Used to retrieve all the items', 'application/json', '')] 
    [EndPointRequestParameter(TAPIDocParameter.TParameterIn.Path, 'Test', 'Path Parameter item Description', false, TAPIDoc.TPrimitiveType.spString, TAPIDoc.TPrimitiveFormat.None, TAPIDoc.TPrimitiveType.spString, '', '')] 
    [EndPointResponseDetails(200, 'Ok', TAPIDoc.TPrimitiveType.spObject, TAPIDoc.TPrimitiveFormat.None, '', '#/definitions/items')] 
    procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); 
    [ResourceSuffix('{item}')] 
    procedure GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); 
    end; 
    {$METHODINFO OFF} 

implementation 
const 
    TestValues: array [0 .. 2] of string = ('a', 'b', 'c'); // It creates an array of string values. 

procedure TTestResource.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); 
var 
    LJSON: TJSONArray; 
    I: Integer; 
begin 
    LJSON := TJSONArray.Create; 
    for I := Low(TestValues) to High(TestValues) do 
    LJSON.Add(MakeJSON(I)); //[{"index":0,"value":"a"},{"index":1,"value":"b"},{"index":2,"value":"c"}] 
    AResponse.Body.SetValue(LJSON, True) // True causes AResponse to free JSON 
end; 

procedure TTestResource.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); 
var 
    I: Integer; 
begin 
    if not TryStrToInt(ARequest.Params.Values['item'], I) then //{"index":I,"value":value} 
    AResponse.RaiseBadRequest('Index expected'); 
    if (I < 0) or (I >= Length(TestValues)) then 
    AResponse.RaiseBadRequest('Index out of range'); 
    AResponse.Body.SetValue(MakeJSON(I), True); 
    // True causes AResponse to free JSON 
end; 

function TTestResource.MakeJSON(I: Integer): TJSONObject; 
begin 
    Result := TJSONObject.Create; 
    Result.AddPair('index', TJSONNumber.Create(I)); //Adds to the JSON object a pair {"index": I}, the index number. 
    Result.AddPair('value', TJSONString.Create(TestValues[I])); //Adds to the the JSON object a pair {"value":String}, the string corresponding to the index number. 

end; 

procedure Register; 
begin 
    RegisterResource(TypeInfo(TTestResource)); 
end; 

initialization 
    Register; 
end. 

Il semble qu'il y ait quelque chose en Exemple de projet manquant dans le code généré par l'assistant de package RAD Studio EMS. Je me demande si quelqu'un a été capable d'utiliser les nouveaux attributs de la documentation EMS pour créer une documentation YAML à partir de son propre package EMS - pas le projet exemple fourni avec RAD Studio?

Quelqu'un d'autre a-t-il ressenti cela? Est-il possible que la méthode get n'ait pas été entièrement implémentée? Y at-il un correctif pour cela (je viens de mettre à jour à RAD Studio 10.2.1)?

Répondre

0

Il ne fonctionnera que si vous exécutez EMSDevServer.exe sans aucune charge, comme ceci:

{"ConfigLoaded":{"Filename":"C:\Users\Public\Documents\Embarcadero\EMS\emsserver.ini","Thread":924}} 
{"DBConnection":{"InstanceName":"gds_db","Filename":"C:\Users\Public\Documents\Embarcadero\EMS\emsserver.ib","Thread":924}} 
{"Licensing":{"Licensed":false,"DefaultMaxUsers":5,"Thread":924}} 
{"RegResource":{"Resource":"Version","Endpoints":["GetVersion"],"Thread":924}} 
{"RegResource":{"Resource":"API","Endpoints":["API","GetAPIYAMLFormat EndPoint","GetAPIYAMLFormat","GetAPIJSONFormat"],"Thread":924}} 
{"RegResource":{"Resource":"Users","Endpoints":["GetUsers","GetUser","GetUserFields","GetUserGroups","SignupUser","LoginUser","AddUser","UpdateUser","DeleteUser"],"Thread":924}} 
{"RegResource":{"Resource":"Groups","Endpoints":["GetGroups","GetGroup","GetGroupFields","AddGroup","UpdateGroup","DeleteGroup"],"Thread":924}} 
{"RegResource":{"Resource":"Installations","Endpoints":["GetInstallations","GetChannels","GetInstallationFields","GetInstallation","AddInstallation","UpdateInstallation","DeleteInstallation"],"Thread":924}} 
{"RegResource":{"Resource":"Push","Endpoints":["Send"],"Thread":924}} 
{"RegResource":{"Resource":"Edgemodules","Endpoints":["GetModules","GetModule","GetResources","GetModuleResources","GetModulesFields","GetResourcesFields","GetModuleResource","RegisterModule","RegisterModuleResource","UpdateModule","UpdateModuleResource","UnregisterModule","UnregisterModuleResource","GetResourceEndpoint","GetResourceEndpointItem","PutResourceEndpoint","PutResourceEndpointItem","PostResourceEndpoint","PostResourceEndpointItem","PatchResourceEndpoint","PatchResourceEndpointItem","DeleteResourceEndpoint","DeleteResourceEndpointItem"],"Thread":924}} 
{"Request":{"Resource":"API","Endpoint":"GetAPIJSONFormat","Method":"GET","User":"(blank)","Time":"06.11.2017 15:42:28","Thread":8672}} 

Avec une charge, il ne fonctionne pas, il est probablement un bug.