Rest in delphi
22 Slides739.62 KB
Rest in delphi
REST (From Wikipedia) Representational State Transfer Stateless between transactions No Official Standard, it is not a protocol, it is an Architectural Style One common use is for interacting with web services, an alternative to Soap (for Example) Uses http verbs (Get, Post, Put, Delete, Patch ) There may be some differences between providers with how they use the verbs
REST (Web Services) HTTPS is (effectively) required Requests and responses can be in HTML, XML, JSON (and query parameters for requests) A basic web page with HTML would meet most if not all the requirements to be a REST service (for Humans) JSON seems to be a common (machine) data format, and mostly what I will talk about Most of this discussion is from the client side
JSON (why) Used by many web services JSON has some handy features You can often select a partial response, (a bit like requesting specific fields in a database query, rather than *), XML tends to be a contract, so all fields need to be supplied. When formatted reasonably it usually makes viewable sense Strictly it doesn’t support comments, which can be annoying, some parsers do allow comments No strict date format/type, which can cause issues ISO8601 date time, and yyyy-mm-dd hh:mm:ss (UTC) seem common
External Tooling You can often use Curl or equivalent to retrieve, and post data (handy for testing) Fiddler (burpsuite, etc) very handy for seeing exactly what got sent, and what got received For resending slightly altered versions For resending a bunch of requests quickly Wireshark, Always handy, somewhat less useful when everything is inside HTTPS. Developer account or Local instance of the Web Service you are connecting too Firefox developer, with Rest Client, Foxy Proxy, etc
REST Client (in Delphi) There are at least a couple of built-in ways to connect to a web service using delphi Using Indy Components Uses OpenSSL Using TRestClient (Since XE5) Uses Hosts Security Infrastructure (Since XE8) Eg Schannel on windows
Rest Client Server Verification (Certificate Checking) By-Default Delphi tends to not verify the server certificate, which is not ideal Can add verification code, simple for Schannel, slightly less so for OpenSSL
REST Client (Indy) TIdHTTP HTTP Client TIdSSLIOHandlerSocketOpenSSL SSL Handler TIdLogFile HTTP(S) Logging intercept Verification None (Default) CA File (Verifies Root certificate is trusted Host also trusted) Can put in a single CA to pin the certificate to that CA Also need some custom verification to verify actual server name FingerPrint Pins the certificate to a specific hash code, was good, now less useful when using Let’s Encrypt Certificates CA Bundle for open SSL https://curl.haxx.se/docs.caextract.html
REST Client (TRestClient) TRestClient TRestRequest TRestResponse Setup Request Response Info Uses Windows Schannel Verification None (Default) Can setup to verify using windows verification readily
JSON Processing Libraries TJSONObject, TJSONArray (Since D2010) originally in DBXJSON, now in System.JSON SuperObject and its relatives are used for much of my JSON processing Both need checking when JSON objects, or Arrays are expected (May return nil) SuperObject uses some sort of hash, so pretty-print of objects may be in a different order to how they came in, which is legal but annoying. (Arrays are kept in order)
Delphi Rest Processing Mostly I have been manually creating write/read functionality to match the server specs I will usually make some sort of connector, and then a set of objects/classes to match the server objects and to handle the tasks I want to perform Then a bunch of other classes to plumb them into a database Things like Swagger exist, which can make documenting Rest interfaces easer (And may allow discovery)
REST Client Demo https://jsonplaceholder.typicode.com/ No authentication/authorization required Made a simple Delphi Demo to retrieve and post data to this site Note: I have not included any encryption/storage in the demos You need to carefully look after the assorted keys and tokens required when connecting to web services
Authentication/Authorization OAUTH A somewhat standard method of authenticating your Application to a web service by your client (who also is a client of the web service) Ex. An Application needs access to a client’s Gmail, to send emails as them. In the past, you might get the client to give the app their Gmail account details, (and probably they would not be happy about it) Using OAUTH, the client can instruct a web service (Gmail in this case), that the app should have specific access rights to their Gmail account (and the app doesn’t know their password)
OAUTH Versions Couple of versions of OAUTH in common use V1.0a and V2.0 V2.0 apparently has lots of options, however a very common one allows you to simply drop the access token into the request headers, usually in an Authorization: Bearer header. Authorization: Bearer MyAppsLongLivedTokenForThisClient V1.0a requires you to generate signature of your request parameters using your apps secret (password) and send that along with the request, as well as the tokens to identify your app, and the client.
OAUTH Flow One Common Flow is You Register your App with the Web Service, and your app will be assigned a couple of Tokens (Effectively a username/password) These tokens are used by your app (Only) The client (who wants to use your app with the web service) is sent (in a browser) by your app to an authorization web page, on the customer facing side of the web service which allows them to accept or deny your app’s request If the client accepts the request, their web browser is redirected to your app, with a short-lived authorization token. Your app can/must turn this token into a long-lived access token (and perhaps a Refresh Token)
OAUTH Flow Cont’d If your app is cloud/web based, the redirect would be to a URL something like https://yourAppsHostName/AuthURL For a desktop app, the redirect will likely be to a URL like http://localhost:PortNo/AuthURL There will usually be query string parameters providing the shortlived token your app can use to get the long-term access token OAUTH playground (Can step through various scenarios) https://www.oauth.com/playground/ https://www.oauth.com/oauth2-servers/tools-and-libraries
OAUTH Misc You are usually the first client for your app (Testing) If the Client decides they don’t want your app to have access to the service anymore, they can login to their services control panel, and remove your app’s access If the web service decides your app is a risk, they can block your app’s access to their web service completely You can remove the app from the services control panel or regenerate its keys causing existing installs of your app to no longer work Easy change for a cloud app May cause a bit of grief for a desktop app
Gmail Demo A demo of a https Gmail send only client Sends emails on your client’s behalf through Gmail Uses Oauth and Rest Current demo uses the superobject JSON libraries Currently it is set up as a test application Would need to get it (and your self/company) setup appropriately Privacy Statement, Website, etc App Verified
Server Side Delphi has its Rest Datasnap functionality http://docwiki.embarcadero.com/RADStudio/Sydney/en/ Tutorial: Using a REST DataSnap Server with an Application an d FireDAC https://www.embarcadero.com/rad-in-action/delphi-labs
Alternate Rest Service Provider Options Mostly for Servers Arpy (Glen Cleidon) Mormot Delphi MVC Framework
SWAGGER (OpenAPI) For Web Services Can make it easy to document your Rest Service Can give a test bed to test your Rest Service Trial how/what to send in a browser https://delphiaball.co.uk/2016/04/22/swagger-yaml-delphi/ Magento has a swagger entry point
End Thank You Questions?