Je to už neuvěřitelných 7 let, kdy jsem se zmínil o Delphi MVC frameworku a musím říct, že když jsem tehdy říkal, že mi přijde jako nejprogresivnější tak jsem nelhal.
Od té doby zrobustněl, bylo přidáno spousta funkcí (jako podpora swaggeru, JWT autentizaci, JSON-RPC 2.0, Cors a desítky dalších), nebudu to tady vyjmenovávat, ale přímo odkáži na github.com/danieleteti/delphimvcframework. Součástí archívu je spousta dem. Výhodou je taky kompletní zdrojový kód.
Cílem dnešního článku je ukázat jak jednoduše vytvoříte základní službu (celý REST full je podobně jednoduchý) odpovídající na vaše pořadavky.
Nebudu vytvářet kompletní server, zakládní kostru vám vygeneruje průvodce, nebo použije některé z dem, třeba z adresare samples\swaggerdoc, ale raději ukážu konkrétní jednu službu.
unit uControlerTown;
interface
uses
System.Generics.Collections, db,
MVCFramework,
MVCFramework.Commons,
MVCFramework.Swagger.Commons,
MVCFramework.Serializer.Commons,
MVCFramework.Middleware.Authentication.RoleBasedAuthHandler,
MVCFramework.Nullables;
const
csServerService = 'DemoService';
type
[MVCNameCase(ncLowerCase)]
TTown = class
private
FName: string;
FPostCode: string;
public
[MVCSwagJsonSchemaField('name', 'town name', True, False)]
property Name: string read FName write FName;
[MVCSwagJsonSchemaField('postcode', 'post code', True, False)]
property PostCode: string read FPostCode write FPostCode;
end;
[MVCPath('/town')]
[MVCSwagAuthentication(atJsonWebToken)]
TCtrlDrevina = class(TMVCController)
public
[MVCPath('/($Id)')]
[MVCHTTPMethod([httpGET])]
{$IFNDEF DEBUG} [MVCRequiresRole('role1')] {$ENDIF}
[MVCSwagSummary('Town section', 'Town by Id', 'GetTown')]
[MVCSwagParam(plPath, 'Id', 'Town id', ptInteger)]
[MVCSwagParam(plQuery, 'params', 'Params', ptString)]
[MVCSwagResponses(200, 'Success', TTown)]
[MVCSwagResponses(401, 'Unauthorized')]
[MVCSwagResponses(500, 'Internal Server Error')]
procedure GetTown(const Id: Integer);
// dalsi metody
end;
implementation
uses
MVCFramework.Controllers.Register;
procedure TCtrlDrevina.GetTown(const Id: Integer);
var
r: TTown;
sParams: string;
function qParam(const sName:string): string;
begin
Result := '';
if Context.Request.QueryStringParamExists(sName) then
Result := Context.Request.QueryParams[sName];
end;
begin
sParams := qParam('params'); // example param query access
r := TTown.Create;
r.Name := 'Zlín';
r.PostCode := '76701';
Render(r);
end;
initialization
TControllersRegister.Instance.RegisterController(TCtrlDrevina, csServerService);
end.
Výsledkem je služba, která po zadání http://localhost:8080/api/town/10?params=test (kde ten začátek je samozřejmě server kde to běží) vrátí JSON.
{"name":"Zlín","postcode":"76701"}
Zároveň je ukázáno, jak se dají předat parametry a jak DMVC provádí mapování na parametry funkce.
Zkusím to rozebrat: na řádcích 20 - 29 definuji model, který vrací služba. Ty MVCSwagJsonSchemaField jsou atributy, které slouží serveru pro vytváření automatické dokumentace pro swagger a jsou nepovinné.
Řádky 33 - 48 popisují rozhraní této podslužby, kdy /town určuje API část v URL a pak jsou jednotlivé podslužby (momentálně jen jedna), a kde řádek 37 a 38 ukazuje, že služba bude mapovat parametr v URL na parametr funkce id, a jedná se o http GET.
Řádek 39 určuje, že pokud to nebude Debug mod, tak bude sekce chráněna autentizací (pro jednuduché ladění) a typ je dokumentován řádkem 34 (k tomu příště, nebo se podívejte do uvedeného dema, nebo samples\jsonwebtoken_roleauth).
Řadek 40 definuje pro swagger sekci a popis (viz screenshot dole), a následující dva řádky popisují 2 parametry - jeden v URL a druhý jako query v URL.
Následující řádky popisují známé http response kódy a jejich význam (tj. to co produkujeme) a nakonec je deklarace vlastní implementační metody.
Vlastní implementace
Vlastní obsluha je jednoduchá jako flákanec, vytvoříme instanci modelu, naplníme daty a dáme render. Render umí záznamy, třídy, pole atd. Samozřejmě reagujeme nějak na parametry, můžeme číst z DB (ideálně přes Connection pool jak jsem popisoval) atd.
No a poslední řádek je registrace naší podslužby mezi ostatní služby produkované DMVC.
Výsledek
Všechny ty věci kolem jsou kvůli swaggeru, což je web nástroj pro dokumentaci a testování. Takže jak to bude vypadat?
Po zobrazení swaggeru (všechno je součástí vašeho serveru) (je vynecháno záhlaví s informacemi o serveru)
Úplně dole jsou rozkliknutelné modely (tj. datové typy).
Rozbalení naší služby nám umožní pracovat s danou službou:
Nyní máte možnost zkoušet volání a pozorovat výsledky. Pozn.: pro začátečníky připomínám, že GET u http je možno zobrazit i ve webovém prohlížeči. Kromě testování je tímto zároveň prováděna dokumentace služby.
Jo a minimální požadavek je momentálně Delphi 10 Seattle.