Blog
All Blog Posts | Next Post | Previous PostIntroducing TMS XData Query Builder and more!
Tuesday, June 22, 2021
We're excited to announce TMS XData 5.2 version with several new great features. TMS XData is the more straightforward way to take your Delphi app to the cloud, allowing you to create secure, robust REST servers along with a huge ecosystem around it. Here are the major features in this release, which also includes several minor improvements and bug fixes.
XData Query Builder
XData allows you to easily query entities from automatic entity set endpoints using a full query syntax. For example, to query customers which name is "Paul" or birthday date is lower then August 1st, 1940, ordered by name in descending order, you can write a code like this:
Customers := Client.List<TCustomer>('$filter=(Name eq ''Paul'') or (Birthday lt 1940-08-01)&$orderby=Name desc');
But now you don't need to worry to write the raw query syntax anymore. The new XData Query Builder allows you to build such filter using a fluent interface which already does some validation (like checking for correct property names) before the data is sent to the server:
Customers := Client.List<TCustomer>(
CreateQuery
.From(TCustomer)
.Filter(
(Linq['Name'] = 'Paul')
or (Linq['Birthday'] < EncodeDate(1940, 8, 1))
)
.OrderBy('Name', False)
.QueryString
);
You can build logical expressions and projections in a similar way you would do with TMS Aurelius criteria.
Receive DTO objects in URL query string
Service operations can now receive DTOs (Delphi objects) from the query string of the request URL (as long the DTO only have properties of scalar types). In this case, each DTO property will be a separated query param. Suppose you have a class TCustomerDTO
which has properties Id
and Name
, then you can declare the method like this:
[HttpGet] function FindByIdOrName(Customer: TCustomerDTO): TList<TCustomer>;
And have your Customer
parameter be received from a request URL like this:
GET /CustomerService/FindByIdOrName?Id=10&Name='Paul'
.
XData queries in service operations
Now, in addition to send queries to automatic CRUD entity set endpoints, you can also benefit from XData query mechanism in service operations. You can now easily receive and process XData query syntax like $filter
, $orderby
, $top
and $skip
in service operations, even for DTOs, and create Aurelius criteria from it. You can declare a service like this:
type IMyService = interface(IInvokable)
[HttpGet] function List(Query: TXDataQuery): TList<TCustomer>;
Which means clients can now invoke the endpoint passing the same $filter
, $orderby
, $top
and $skip
parameters, like this:
GET /MyService/List/?$filter=Name eq 'Foo'&$orderby=Name&$top=10&$skip=30
Or, of course, passing the raw filter string with TXDataClient
:
Customer := Client.Service<IMyService>
.List('$filter=Name eq 'Foo'&$orderby=Name&$top=10&$skip=30');
Or even using the brand new XData query builder fluent interface:
Customer := Client.Service<IMyService>.List(
CreateQuery.From(TCustomer)
.Filter(Linq['Name'] eq 'Foo')
.OrderBy('Name')
.Top(10).Skip(30)
.QueryString
);
From server-side, you can create an Aurelius criteria automatically from the passed XData query:
function TMyService.List(Query: TXDataQuery): TList<TCustomer>;
begin
Result := TXDataOperationContext.Current
.CreateCriteria<TCustomer>(Query).List;
end;
Not only that, you can even create a criteria from a query based on a DTO object:
function TMyService.List(Query: TXDataQuery): TList<TCustomer>;
begin
Result := TXDataOperationContext.Current
.CreateCriteria<TCustomer>(Query, TCustomerDTO).List;
end;
In the example above, even though you are creating a criteria for the TCustomer
class, the query will be validated based on the TCustomerDTO
class. This means XData will only accept queries that use properties from TCustomerDTO
. For example, if the filter string is $filter=Status eq 2
, even if the Status
property exists in TCustomer
, if it does not exist in class TCustomerDTO
the query will not be accepted and an error "property Status does not exist" will return to the client.
And there is more!
There are even more new features:
-
Nullable<T>
types are now supported in plain Delphi objects (in addition to existing support in Aurelius entities). When using plain Delphi objects as DTOs, like when receiving or returning them in service operations, they are now properly serialized/deserialized as JSON. -
A new Forward middleware processes
x-forwarded-*
headers for improved behavior of Sparkle servers behind reverse or edge proxies. -
A new "Sparkle app" demo shows how to create a Windows XData server application working as both VCL application (for Debug) or Windows service (for Release).
Want to know more?
Great new features in this release! If you are already a TMS XData user, please comment below, let us know what do you think about this exciting release!
If want to know more about XData, you can always check the documentation of course, but also don't hesitate to contact us to get help. Also check the existing content in our channels: subscribe to our e-mail newsletter, follow our Facebook page and subscribe to our YouTube channel!
(*) Photo by Adyant Pankaj on Unsplash
Wagner Landgraf
This blog post has received 1 comment.
All Blog Posts | Next Post | Previous Post
Rick Hazell