Erstellen der EMS Pets-Ressource
Nach oben zu Tutorial: Verwenden eines EMS-Clients für den Zugriff auf eine benutzerdefinierte EMS-Ressource
Inhaltsverzeichnis
Erstellen Sie für dieses Tutorial zunächst eine neue EMS-Ressource, die alle verfügbaren Methoden bereitstellt (weitere Informationen dazu finden Sie unter Übersicht über EMS-Ressourcen), und implementieren Sie sie.
Die EMS Pets-Ressource dieses Tutorials speichert Informationen über Haustiere (wie Name und Art) in einer Datei auf dem EMS-Server. Die EMS Pets-Ressource implementiert die verfügbaren Endpunkte, und die EMS Pets-Client-Anwendung kann die Liste der Haustiere abrufen oder die zu den Tieren gespeicherten Informationen durch Aufruf dieser EMS Pets-Ressourcenendpunkte ändern.
Erstellen der EMS Pets-Ressource
Sie müssen eine neue EMS-Ressource erstellen und die bereitgestellten EMS-Ressourcenendpunkte festlegen. Weitere Informationen finden Sie unter Übersicht über EMS-Ressourcen.
- Öffnen Sie in RAD Studio den EMS-Package-Experten.
- Für Delphi: Datei > Neu > Weitere > Delphi-Projekte > EMS > EMS-Package.
- Wählen Sie "Package mit Ressource erstellen".
- Fügen Sie den Namen und den Dateityp für die EMS-Ressource hinzu:
- Ressourcenname: Pets
- Dateityp: Unit
- Wählen Sie die EMS-Endpunkte aus, die die EMS-Ressource bereitstellt. Wählen Sie für dieses Tutorial alle Endpunkte aus.
- Klicken Sie auf die Schaltfläche Fertig stellen.
- Benennen Sie in der Projektverwaltung die Unit in PetsResource um.
- Speichern Sie das Projekt.
Die Registerkarte "Code" enthält den Code für die erstellte EMS-Ressource:
- Für 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;
Erstellen des Pet-Typs
Sie müssen ein benutzerdefiniertes Objekt erstellen, das zwischen dem EMS-Client und den EMS-Server-Endpunktmethoden anhand von JSON-Objekten übergeben wird.
- Hinweis: Sie müssen diese Daten-Unit in der EMS-Client-Anwendung verwenden, um die Daten zu serialisieren.
Erstellen Sie wie folgt eine neue Pet type-Unit für Ihre Anwendung:
- Klicken Sie in der Projektverwaltung mit der rechten Maustaste auf das Projekt, und wählen Sie | Neue hinzufügen > Unit.
- Benennen Sie die Unit in PetType um.
- Erstellen Sie wie folgt den neuen Record TPet:
- Für 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;
- Fügen Sie der Unit den folgenden Code hinzu:
- Für Delphi:
constructor TPet.Create(const AId: integer; const AName, AKind: string); begin FName := AName; FKind := AKind; FId := AId; end;
- Sie müssen in Ihrer Unit die Klasse TPetJSON erstellen, um das Pet-Objekt zu serialisieren. Definieren Sie es wie folgt:
- Für 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;
- Fügen Sie die folgenden uses-Klauseln hinzu:
- Für Delphi:
uses System.JSON, System.Generics.Collections;
-
Implementieren Sie die Methoden Ihrer Unit.
- Für 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;
Hinzufügen des Pets-Managers
In diesem Tutorial werden die Pets-Daten in einer Datei (pets.ini
) auf dem EMS-Server gespeichert. Um auf die Daten dieser Datei zuzugreifen und sie zu verwalten, wird die neue Unit PetsManager in der EMS Pets-Ressource erstellt.
- Klicken Sie in der Projektverwaltung mit der rechten Maustaste auf das Projekt, und wählen Sie Neue hinzufügen > Unit
- Benennen Sie die Unit in PetsManager um.
- Erstellen Sie wie folgt die neue Klasse TPetsManager:
- Für 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;
- Fügen Sie die folgenden uses-Klauseln hinzu:
- Für Delphi:
uses System.SysUtils, System.IniFiles, System.Generics.Collections, PetType, System.Classes, System.StrUtils, System.Types;
- Fügen Sie der Unit den folgenden Code hinzu:
- Für 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;
Hinzufügen der Implementierung zu den EMS-Ressourcenendpunkten
Sie müssen die Implementierung der EMS-Endpunktmethoden hinzufügen.
- Fügen Sie die folgenden uses-Klauseln hinzu:
- Für Delphi:
uses PetType, PetsManager;
- Erstellen Sie in Ihrer EMS-Ressource die folgende private-Variable:
- Für Delphi:
private FPetsManager: TPetsManager;
-
Fügen Sie der Unit den folgenden Code hinzu:
- Für 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;
Laden der EMS-Ressource auf den EMS-Server
Der EMS-Server lädt die EMS Pets-Ressource und stellt die EMS Pets-Ressourcenendpunkt für die EMS-Client-Anwendungen bereit.
- Überprüfen Sie, ob der EMS-Server in Ihrem System eingerichtet ist.
- Drücken Sie F9, oder wählen Sie Start > Start, um die EMS Pets-Ressource zu laden.
Das Fenster des EMS-Entwicklungsservers wird geöffnet. Im Protokollbereich können Sie das Laden der EMS Pets-Ressource verfolgen.
{"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}}