Modern applications rarely exist in isolation. Connecting to web services is essential for tasks like fetching real-time data, authentication, and cloud integration. REST (Representational State Transfer) is the most common architectural style for web service APIs.
1. Understanding RESTful APIs
REST defines a set of constraints for creating web services that communicate primarily over the HTTP protocol.
- Resources: Every piece of data (e.g., a user, a product) is treated as a resource, identified by a URL (Uniform Resource Locator).
- HTTP Methods: Standard HTTP verbs are used to define the action:
- GET: Retrieve a resource (Read).
- POST: Create a new resource.
- PUT/PATCH: Update an existing resource.
- DELETE: Remove a resource.
- Data Format: Data is typically exchanged using JSON (JavaScript Object Notation) or, less commonly, XML.
2. The REST Client Components
Delphi provides a set of highly optimized non-visual components, primarily in the REST.Client unit, for consuming REST services.
| Component | Class Name | Purpose |
TRESTClient | Connection | Defines the constant base URL for the service (e.g., https://api.weather.com/v1). |
TRESTRequest | Request Definition | Defines the specific resource path (/forecast), the HTTP Method (GET), and any parameters. |
TRESTResponse | Response Handling | Receives the result from the service, including the HTTP status code and the raw JSON/data payload. |
Basic Workflow
- Set
TRESTClient.BaseURL. - Set
TRESTRequest.Resource(the part after the Base URL). - Set
TRESTRequest.Method(e.g.,rmGET). - Execute the request (
TRESTRequest.Execute). - Process the response (
TRESTResponse.Content).
3. Handling JSON Data
JSON is the standard format for REST data exchange. Delphi provides classes in the System.JSON unit to easily parse and generate JSON structures.
A. Parsing JSON
The raw response content (TRESTResponse.Content) is a string that must be parsed into an object structure. The root JSON object is represented by TJSONObject and the root array by TJSONArray.
uses
System.JSON; // Required for JSON classes
procedure TForm1.ProcessWeatherData(const JSONText: String);
var
JSONObject: TJSONObject;
CityName: String;
Temperature: Double;
begin
// Create the root object from the response text
JSONObject := TJSONObject.ParseJSONValue(JSONText) as TJSONObject;
try
// Access values by name
CityName := JSONObject.GetValue('city').Value;
// Nested access is common
Temperature := (JSONObject.GetValue('current') as TJSONObject).GetValue<TJSONNumber>('temp_c').AsDouble;
lblCity.Caption := CityName;
lblTemp.Caption := FloatToStrF(Temperature, ffFixed, 8, 1) + ' C';
finally
// Always free the root JSON object, which frees all nested objects
JSONObject.Free;
end;
end;
Generics Note: Using
GetValue<TJSONNumber>('temp_c')is a type-safe way to retrieve a JSON value and cast it to the expected JSON type.
B. Sending JSON (POST/PUT)
When sending data, you construct the TJSONObject and assign its string representation to the request body.
procedure TForm1.SendNewUser(UserName: String);
var
JSONPayload: TJSONObject;
begin
// 1. Create the JSON structure
JSONPayload := TJSONObject.Create;
try
JSONPayload.AddPair('username', UserName);
JSONPayload.AddPair('isActive', True);
// 2. Configure the request
RESTRequest1.ClearBody;
RESTRequest1.Method := rmPOST;
RESTRequest1.AddBody(JSONPayload); // Add the structured JSON to the request body
// 3. Execute and check response code
RESTRequest1.Execute;
if RESTResponse1.StatusCode = 201 then // 201 Created is a common success code
ShowMessage('User created successfully.')
else
ShowMessage('Error: ' + RESTResponse1.StatusText);
finally
JSONPayload.Free; // Free the payload object
end;
end;
4. Direct Data Binding (TRESTResponseDataSetAdapter)
For services that return a list of uniform data (like a list of customers), you can bypass manual JSON parsing and use a TRESTResponseDataSetAdapter to directly link the REST response to data-aware controls (TDBGrid, etc.).
- Place
TRESTResponseDataSetAdapteron the form. - Link
Responseproperty to yourTRESTResponsecomponent. - Link
Adapterproperty of aTFDMemTable(an in-memory dataset component) to the adapter. - Set the
RootElementproperty on the adapter to point to the main JSON array in the response (e.g.,'data'or'customers').
This automatically maps the JSON structure to dataset fields, making it instantly displayable in a TDBGrid via a TDataSource.
