Création de la ressource EMS Pets
Remonter à Tutoriel : Utilisation d'un client EMS pour accéder à une ressource EMS personnalisée
Sommaire
Pour commencer ce tutoriel, créez une nouvelle ressource EMS qui expose toutes les méthodes disponibles (voir Présentation des ressources EMS pour plus d'informations) et les implémente.
La ressource EMS Pets de ce tutoriel stocke des informations sur des animaux de compagnies (par exemple, leur nom et leur type) dans un fichier qui se trouve sur le serveur EMS. La ressource EMS Pets implémente les points de terminaison disponibles et l'application client EMS Pets peut récupérer la liste des animaux de compagnie ou modifier les informations stockées sur eux en appelant ces points de terminaison de ressource EMS Pets.
Création de la ressource EMS Pets
Vous devez créer une ressource EMS et définir les points de terminaison de ressource EMS qui sont exposés. Pour plus d'informations, voir Présentation des ressources EMS.
- Ouvrez l'expert Package EMS dans RAD Studio.
- Pour Delphi : Fichier > Nouveau > Autre > Projets Delphi > EMS > Package EMS.
- Sélectionnez Créer un package avec la ressource.
- Ajoutez le nom de la ressource EMS et le type de fichier :
- Nom de ressource : Pets
- Type de fichier : Unité
- Sélectionnez les points de terminaison EMS que la ressource EMS expose. Pour ce tutoriel, sélectionnez tous les points de terminaison.
- Cliquez sur le bouton Terminer.
- Dans le Gestionnaire de projets, renommez l'unité en PetsResource.
- Enregistrez le projet.
Vous pouvez voir la ressource EMS créée dans l'onglet Code :
- Pour Delphi :
[ResourceName('Pets')]
{$METHODINFO ON}
TPetsResource = class
private
FPetsManager: TPetsManager;
function GetModuleDirectory: string;
procedure CheckManager;
function IdFromRequest(const ARequest: TEndpointRequest): Integer;
public
destructor Destroy; override;
published
[EndpointName('GetPets')]
procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
[EndpointName('GetPet')]
[ResourceSuffix('{item}')]
procedure GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
[EndpointName('AddPet')]
procedure Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
[EndpointName('UpdatePet')]
[ResourceSuffix('{item}')]
procedure PutItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
[EndpointName('DeletePet')]
[ResourceSuffix('{item}')]
procedure DeleteItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
end;
{$METHODINFO OFF}
procedure Register;
Création de l'unité Pet Type
Vous devez créer un objet défini par l'utilisateur qui sera transmis entre les méthodes de points de terminaison du client EMS et du serveur EMS en utilisant des objets JSON.
- Remarque : Vous devez utiliser cette unité de données dans l'application client EMS pour sérialiser les données.
Créez une nouvelle unité Pet type pour votre application, en procédant comme suit :
- Dans le Gestionnaire de projets | cliquez avec le bouton droit dans le projet | Ajouter nouveau > Unité.
- Renommez l'unité en PetType.
- Créez un nouvel enregistrement TPet comme suit :
- Pour Delphi :
TPet = record private FId: integer; FKind: string; FName: string; public constructor Create(const AId: Integer; const AName, AKind: string); property Name: string read FName write FName; property Kind: string read FKind write FKind; property Id: integer read FId write FId; end;
- Ajoutez le code suivant à votre unité :
- Pour Delphi :
constructor TPet.Create(const AId: integer; const AName, AKind: string); begin FName := AName; FKind := AKind; FId := AId; end;
- Pour sérialiser l'objet Pet, vous devez créer la classe TPetJSON dans votre unité. Définissez-la de la façon suivante :
- Pour Delphi :
TPetJSON = class public class function JSONToPet(const AJSON: TJSONValue): TPet; static; class function JSONToPets(const AJSON: TJSONArray): TArray<TPet>; static; class procedure PetsToJSON(const APets: TArray<TPet>; const AJSON: TJSONArray); static; class procedure PetToJSON(const APet: TPet; const AJSON: TJSONObject); static; end;
- Ajoutez les clauses uses suivantes :
- Pour Delphi :
uses System.JSON, System.Generics.Collections;
-
Implémentez les méthodes de votre unité.
- Pour Delphi :
class function TPetJSON.JSONToPet(const AJSON: TJSONValue): TPet; begin Result := TPet.Create(AJSON.GetValue<integer>('id'), AJSON.GetValue<string>('kind'), AJSON.GetValue<string>('name')); end; class procedure TPetJSON.PetToJSON(const APet: TPet; const AJSON: TJSONObject); begin AJSON.AddPair('id', TJSONNumber.Create(APet.FId)); AJSON.AddPair('kind', TJSONString.Create(APet.FKind)); AJSON.AddPair('name', TJSONString.Create(APet.FName)); end; class function TPetJSON.JSONToPets(const AJSON: TJSONArray) : TArray<TPet>; var LValue: TJSONValue; LList: TList<TPet>; begin LList := TList<TPet>.Create; try for LValue in AJSON do LList.Add(TPetJSON.JSONToPet(LValue)); Result := LList.ToArray; finally LList.Free; end; end; class procedure TPetJSON.PetsToJSON(const APets: TArray<TPet>; const AJSON: TJSONArray); var LPet: TPet; LJSONObject: TJSONObject; begin for LPet in APets do begin LJSONObject := TJSONObject.Create; PetToJSON(LPet, LJSONObject); AJSON.Add(LJSONObject); end; end;
Ajout de l'unité Pets Manager
Ce tutoriel montre comment stocker les données Pets dans un fichier qui se trouve sur le serveur EMS (pets.ini
). Pour accéder aux données de ce fichier et les gérer, une nouvelle unité appelée PetsManager est créée dans la ressource EMS Pets.
- Dans le Gestionnaire de projets | cliquez avec le bouton droit dans le projet | Ajouter nouveau > Unité
- Renommez l'unité en PetsManager.
- Créez la nouvelle classe TPetsManager comme suit :
- Pour Delphi :
type TPetsManager = class FUserID: string; FIniFile: TIniFile; private function EncodePet(const AName: string; const AKind: string): string; function DecodePetLine(const ALine: string; const AField: integer): string; public constructor Create(const ADirectory: string); destructor Destroy; override; function GetPets: TArray<TPet>; function GetPet(const AId: Integer; out APet: TPet): Boolean; procedure UpdatePet(const AId: Integer; const APet: TPet); procedure AddPet(const APet: TPet); function DeletePet(const AId: Integer): Boolean; function PetExists(const AId: Integer): Boolean; end;
- Ajoutez les clauses uses suivantes :
- Pour Delphi :
uses System.SysUtils, System.IniFiles, System.Generics.Collections, PetType, System.Classes, System.StrUtils, System.Types;
- Ajoutez le code suivant à votre unité :
- Pour Delphi :
constructor TPetsManager.Create(const ADirectory: string); var LPath: string; begin LPath := IncludeTrailingPathDelimiter(ExpandFileName(ADirectory)) + 'pets.ini'; FIniFile := TIniFile.Create(LPath); FUserID := '0000'; end; // Procedure to add a pet to the pets.ini file procedure TPetsManager.AddPet(const APet: TPet); begin FIniFile.WriteString(FUserID, APet.Id.ToString, EncodePet(APet.Name, APet.Kind)); end; // Function to check if a pet exists in the pets.ini file function TPetsManager.PetExists(const AId: Integer): Boolean; begin Result := FIniFile.ValueExists(FUserID, AId.ToString); end; // Function to delete a pet from the pets.ini file function TPetsManager.DeletePet(const AId: Integer): Boolean; begin Result := PetExists(AId); if Result then FIniFile.DeleteKey(FUserID, AId.ToString); end; // Destructor destructor TPetsManager.Destroy; begin FIniFile.Free; inherited; end; // Function to get a specific pet from the pets.ini file function TPetsManager.GetPet(const AId: Integer; out APet: TPet): Boolean; var LName: string; LKind: string; begin Result := PetExists(AId); if Result then begin LName := DecodePetLine(FIniFile.ReadString(FUserID, AId.ToString, ''), 1); LKind := DecodePetLine(FIniFile.ReadString(FUserID, AId.ToString, ''), 0); APet := TPet.Create(AId, LName, LKind); end; end; // Function to get all pets from the pets.ini file function TPetsManager.GetPets: TArray<TPet>; var LList: TList<TPet>; LPet: TPet; LSection: TStrings; I: integer; begin LSection := nil; LList := nil; try LSection := TStringList.Create; LList := TList<TPet>.Create; FIniFile.ReadSectionValues(FUserID, LSection); for I := 0 to LSection.Count - 1 do begin LPet := TPet.Create(LSection.Names[I].ToInteger, DecodePetLine(LSection.ValueFromIndex[I], 1), DecodePetLine(LSection.ValueFromIndex[I], 0)); LList.Add(LPet); end; Result := LList.ToArray; finally LList.Free; LSection.Free; end; end; // Function to update a pet from the pets.ini file procedure TPetsManager.UpdatePet(const AId: Integer; const APet: TPet); begin if PetExists(AId) then FIniFile.DeleteKey(FUserID, AId.ToString); FIniFile.WriteString(FUserID, AId.ToString, EncodePet(APet.Name, APet.Kind)); end; // Function to encode the data (to be saved in the pets.ini file) function TPetsManager.EncodePet(const AName: string; const AKind: string): string; var LPet: string; begin LPet := AName + ',' + AKind; Result := LPet; end; // Function to decode a line from the pets.ini file function TPetsManager.DecodePetLine(const ALine: string; const AField: integer): string; var LPetField: TStringDynArray; begin LPetField := SplitString(ALine, ','); Result := LPetField[AField]; end;
Ajout de l'implémentation aux points de terminaison de ressource EMS
Vous devez ajouter l'implémentation des méthodes de points de terminaison EMS.
- Ajoutez les clauses uses suivantes :
- Pour Delphi :
uses PetType, PetsManager;
- Créez la variable privée suivante dans votre ressource EMS :
- Pour Delphi :
private FPetsManager: TPetsManager;
-
Ajoutez le code suivant à votre unité :
- Pour Delphi :
procedure TPetsResource.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LPets: TArray<TPet>; LJSON: TJSONArray; begin LJSON := nil; try CheckManager; LPets := FPetsManager.GetPets; LJSON := TJSONArray.Create; TPetJSON.PetsToJSON(LPets, LJSON); AResponse.Body.SetValue(LJSON, True) except LJSON.Free; raise; end; end; procedure TPetsResource.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LId: Integer; LPet: TPet; LJSON: TJSONObject; begin LId := IdFromRequest(ARequest); CheckManager; if FPetsManager.GetPet(LId, LPet) then begin LJSON := TJSONObject.Create; try TPetJSON.PetToJSON(LPet, LJSON); AResponse.Body.SetValue(LJSON, True); except LJSON.Free; raise; end; end else AResponse.RaiseNotFound('', Format('Id not found: %d', [LId])); end; procedure TPetsResource.Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LJSON: TJSONObject; LPet: TPet; begin if ARequest.Body.TryGetObject(LJSON) then begin CheckManager; LPet := TPetJSON.JSONToPet(LJSON); if FPetsManager.PetExists(LPet.Id) then AResponse.RaiseDuplicate('', Format('Can not add duplicate Id: %d', [LPet.Id])); FPetsManager.AddPet(LPet); end else AResponse.RaiseBadRequest('', 'JSON expected'); end; procedure TPetsResource.PutItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LId: Integer; LPet: TPet; LJSON: TJSONObject; begin LId := IdFromRequest(ARequest); if ARequest.Body.TryGetObject(LJSON) then begin CheckManager; LPet := TPetJSON.JSONToPet(LJSON); if not FPetsManager.PetExists(LId) then AResponse.RaiseNotFound('', Format('Can not update unknown Id: %d', [LId])); FPetsManager.UpdatePet(LId, LPet); end else AResponse.RaiseBadRequest('', 'JSON expected'); end; procedure TPetsResource.CheckManager; begin if FPetsManager = nil then FPetsManager := TPetsManager.Create(GetModuleDirectory); end; procedure TPetsResource.DeleteItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LId: Integer; begin LId := IdFromRequest(ARequest); CheckManager; if not FPetsManager.DeletePet(LId) then AResponse.RaiseNotFound('', Format('Can not delete unknown Id: %d', [LId])); end; destructor TPetsResource.Destroy; begin FPetsManager.Free; inherited; end; function TPetsResource.GetModuleDirectory: string; begin Result := ExtractFilePath(StringReplace(GetModuleName(HInstance), '\\?\', '', [rfReplaceAll])); end; function TPetsResource.IdFromRequest(const ARequest: TEndpointRequest): Integer; var LItem: string; begin LItem := ARequest.Params.Values['item']; if not TryStrToInt(LItem, Result) then EEMSHTTPError.RaiseBadRequest('', Format('Id is not an integer: "%s"', [LItem])); end; procedure Register; begin RegisterResource(TypeInfo(TPetsResource)); end;
Chargement de votre ressource EMS sur le serveur EMS
Le serveur EMS charge la ressource EMS Pets et expose les points de terminaison de ressource EMS Pets aux applications client EMS.
- Vérifiez que le serveur EMS est configuré dans votre système.
- Pour charger la ressource EMS Pets, appuyez sur F9 ou sélectionnez Exécuter > Exécuter.
La fenêtre Serveur de développement EMS est maintenant ouverte. Dans le volet Journal, vous voyez la ressource EMS Pets en cours de chargement.
{"Load":{"Filename":"C:\Users\Public\Documents\Embarcadero\Studio\15.0\Bpl\PetsResourcePackage.bpl","Thread":4072}} {"RegUnit":{"Filename":"C:\Users\Public\Documents\Embarcadero\Studio\15.0\Bpl\PetsResourcePackage.bpl","Filename":"PetsResource","Thread":4072}} {"RegResource":{"Resource":"Pets","Endpoints":["GetPets","GetPet","AddPet","UpdatePet","DeletePet"],"Thread":4072}}