Blog

All Blog Posts  |  Next Post  |  Previous Post

GraphQL, workflow engine, multitenancy and more: what you will do with Delphi in 2021

Bookmarks: 

Monday, February 15, 2021

Here at TMS, we are working on so much new exciting frameworks and features that I decided to share with you what we expect to bring to you in 2021!

Photo by Rhett Wesley on Unsplash


Photo by Rhett Wesley on Unsplash

First, a disclaimer: this is not an official commitment. Some of the things listed here might be delayed or not be released at all. But of course, that's not our intention, since we are listing it here. We want to (and probably will) release all of this in 2021. But, since unexpected things might happen, we can never guarantee what will happen in future. One second thing: thislist only covers what is coming around TMS Business line of products. There is much more to come from TMS in 2021!

I was going to title this post as "TMS Business Roadmap for 2021". But I thought that the current title brings more attention and curiosity. And it looks like it worked, thanks for coming! ??

Ok, jokes aside, another reason is that we still don't know if all of the libraries, features and technologies listed here will be part of the TMS Business bundle, and the original title could be misleading.

But regardless, everything listed here will for sure be smoothly integrated with TMS Business - either using ORM (TMS Aurelius) or REST/JSON framework (TMS XData), or any other core product, what is for sure is that everything listed here makes up a huge ecosystem around TMS Business technologies.

An exciting year is coming ahead! So, without further ado, this is what we expect to bring to Delphi world this year, with TMS Business.


GraphQL

TMS is bringing GraphQL to Delphi! We have it already in a beta state, the core is complete, all is going fine. We still need to document everything, and add a few more features here and there, but it's in a very advanced stage.

This teaser video shows GraphQL server in action, written in Delphi! The frontend is GraphQL Playground JS framework, but still being served via a Delphi server.

Delphi GraphQL Hello World


The relevant parts of the code used to build the server in the video are the following. First, the GraphQL schema is built:

SchemaDocument := TGraphQLDocumentParser.ParseSchema(
    'type Query { hello(name: String!): String }');
  Schema := TGraphQLSchemaBuilder.Build(SchemaDocument);

  Schema.SetResolver('Query', 'hello', function(Args: TFieldResolverArgs): TValue
    begin
      Result := 'Hello, ' + Args.GetArgument('name').AsString;
    end
  );


Then, the endpoints for the GraphQL API and the GraphQL Playground are created:

  ADispatcher.AddModule(
    TGraphQLServerModule.Create('http://+:2001/tms/graphql', FSchema));

  ADispatcher.AddModule(
    TGraphQLPlaygroundModule.Create('http://+:2001/tms/playground', '/tms/graphql'));


And that's it for the "Hello, world" demo!


TMS Auth

A complete framework for adding authentication to your application, with user, roles and permissions management and providing features like login, registration, e-mail confirmation and more.

Relying on Aurelius ORM and XData REST framework, with a few lines of code you will get all your database setup and have an authentication API server running, with lots of features.

Well, it's said one picture is worth a thousand words, so here is an example of the available API out of box:

Auth Swagger Auth Swagger 2


And these are screenshots of an existing app built with TMS Web Core which is already using TMS Auth for user registration and login:

Auth User Registration


It will never been as easy to add user and permissions management and login system to your Delphi application and server!


BPM Workflow

A full workflow engine is coming. You might ask what is the difference between this new library and TMS Workflow Studio.

It's a night and day difference. TMS Workflow Studio is nice product, but it was made 13 years ago with a different goal in mind - desktop VCL applications - and when lots of technologies didn't even exist, and even several TMS products. Cross-platform, REST servers, ORM, cloud applications.

This new project is a workflow engine written from scratch, with all modern technologies and paradigms in mind. It will have a REST API, it will be cross-database, thread-safe, scalable, and of course will have lots of new features.

The following workflow, for example:

Renewal Process Workflow


Can be built from code this way:

RenewalProcess := TProcessBuilder.CreateProcess
    .Variable('process_id')
    .StartEvent
    .Condition(GroupedCondition([
      TRenewalAllowedCondition.Create,
      SubscriptionNotInAnyProcess
    ]))
    .Activity(SetProcessStatus(TProcessStatus.processing))
    .Activity(IssueInvoice)
    .ExclusiveGateway.Id('gateway1')
      .Condition(THasErrorCondition.Create)
      .Activity(TRenewalFailureActivity.Create).Id('renewal_failure')
      .Activity(SetProcessStatus(TProcessStatus.failed))
      .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsPaid)
      .Activity(RenewSubscription).Id('renew_subscription')
      .ExclusiveGateway.Id('gateway4')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway4')
        .Activity(TRenewalSuccessActivity).Id('renewal_success')
        .Activity(SetProcessStatus(TProcessStatus.succeeded))
        .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsOpen)
      .Activity(ChargePayment).Id('charge_payment')
      .Activity(GetPaymentStatus).Id('get_payment_status')
      .ExclusiveGateway.Id('gateway2')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(GroupedCondition(
          TConditionOperator._or, [PaymentIsCanceled, PaymentIsFailed]))
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(PaymentIsSucceeded)
        .ExclusiveGateway.Id('gateway3')
          .Condition(InvoiceIsPaid)
          .LinkTo('renew_subscription')
        .GotoElement('gateway3')
          .Condition(InvoiceIsOpen)
          .LinkTo('charge_payment')
    .Done;
end;


And can be executed in a thread queue, can be instantiated using a REST API, and many more to come. Actually, you can follow what is being developed so far in its GitHub repository. We are still working on it of course, in both features and licensing terms.


REST Server Authorization

TMS XData, our amazing library for building REST APIs and multitier applications, will have an authorization mechanism that will be very easy to use.

Developers will be able to just add authorization attributes to methods (service operations) or entities (automatic CRUD endpoints) and everything will be applied accordingly. Fine-tuning the protection of your REST API will never be as simple.

  [Authorize]
  IDocumentService = interface(IInvokable)
    procedure Insert(Value: TDoc);

    [AuthorizeScopes('user, editor')]
    procedure Modify(Value: TDoc);

    [AuthorizeScopes('admin')]
    procedure Delete(DocId: string);

    [AuthorizeClaims('email')]
    procedure Approve(DocId: string);
  end;


In the example above, all methods (endpoints) require authentication, because the interface has an Authorize attribute that propagates to all methods. So, to invoke Insert, user must be authenticated. Still, to invoke Modify, the user must be authenticated and have either user or editor scope in its credentials. He must be admin to invoke Delete, and finally to approve a document, user must have an email in its claims.

It's also worth noting that the same strategy applies to entities that generate automatic CRUD endpoints:

  [Entity, Automapping]
  [EntityAuthorize]
  [EntityAuthorizeScopes('editor', [TEntitySetPermission.Modify, TEntitySetPermission.Insert])]
  [EntityAuthorizeScopes('admin', [TEntitySetPermission.Delete])]
  TCustomer = class
  {...}
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
  end;


To access customer endpoints, user must be authenticated. But he must have editor privileges to modify and insert (PUT and POST) and must be admin to invoke DELETE. Easy and straightforward.


Development for the web: even easier

TMS XData is smoothly integrated with TMS Web Core, the TMS framework to build web applications. It provides easy-to-use, high-level client classes to access XData servers from Web Core applications. With the amazing release of TMS Web Core 1.6, several language features were introduced, like generics, async/await, attributes, among others.

This will make TMS XData client objects easier than ever to be used in web applications. The experience will be pretty similar to VCL/FMX applications, like retrieving entity objects from the server without having to deal with JSON directly and invoking endpoints using interfaces without having to worry about HTTP methods or URL endpoints.

And even more, async/await can be used. As an example, invoking a XData REST API endpoint asynchronously will be as easy as doing this:

PendingOrders := await(XClient.List<TOrder>('$filter=Status eq pending'));
if PendingOrders.Count = 0 then
  Exit; // no pending orders to process


The single line above will build the HTTP request with proper URL endpoint and HTTP method, invoke it, deserialize the returned JSON into a list of TOrder objects, and all asynchronously! The await function will guarantee that the next line will be executed only after the async execution is executed. Can't get easier than that.


Global filters and multitenancy

Our state-of-art ORM for Delphi, TMS Aurelius, will have amazing additions this year. One of them is the global filter mechanism. Users will be able to define filters globally, including parameters, and choose which entities will have it applied.

While global filters can obviously be used for any purpose, using it to build multitenant applications is the first one that comes to mind. Consider the following entity class mapped with filtering attributes:

  [Entity, Automapping]
  [Filter('Multitenant')]
  [FilterDef('Multitenant', '{TenantId} = :tenantId')]
  [FilterDefParam('Multitenant', 'tenantId', TypeInfo(string))]
  TProduct = class
  private
    FId: Integer;
    FName: string;
    FTenantId: string;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
    property TenantId: string read FTenantId write FTenantId;
  end;


You can use the class normally, without any filter. But you can also enable the "Multitenant" filter like this:

  Manager.EnableFilter('Multitenant')
    .SetParam('tenantId', 'acme');
  Products := Manager.Find<TProduct>.OrderBy('Name').List;


After you've enabled the "Multitenant" filter passing the proper id, you can use the Aurelius object manager as usual. But any request you do, like in the example, asking a list of products, will add the tenant filter.

Aurelius will not only allow global filters for queries, but also will allow you to enforce the filter in INSERT, UPDATE and DELETE operations:

  FEnforcer := TFilterEnforcer.Create('Multitenant', 'TenantId', 'FTenantId');
  FEnforcer.AutoComplyOnInsert := True;
  FEnforcer.AutoComplyOnUpdate := True;
  FEnforcer.Activate(TMappingExplorer.Get('Samples'));


Thus, you can simply create or modify a product as you would usually do in single tenant application, but the filter enforcer will make sure to set data to the proper tenant id (or raise an error if the tenant is wrong, depending on your configuration).

Building single-database multitenant applications with TMS Aurelius is already possible, of course. But it will be really easy with the upcoming features. And not only that: building multi-database multitenant applications will also be easy with the new TMultiTenantConnectionPool:

  FMultiPool := TMultiTenantConnectionPool.Create(
    TXDataHttpHeaderTenantResolver.Create('tenant-id'),
    TDBConnectionPoolFactory.Create
    );


The pool will automatically choose the correct database based on the HTTP header tenant-id - or any other criteria you might choose. All transparently.

In summary: you will be able to build your app as if you are coding for single tenant applications, and let Aurelius do everything under the hood to make it multitenant, with minimum effort and in a robust and reliable way.


Data validation

Another great feature coming is data validation. Again, you can already do it using events, but soon it will be orders of magnitude easier. You will be able to add validators to your entities in several ways, attributes being the most common (irrelevant parts of the following class declaration removed for clarity):

  TCustomer = class
  private
    [Required]
    FName: string;
    
    [EmailAddress]
    FEmail: string;
  
    [DisplayName('class rate')]
    [Range(1, 10, 'Values must be %1:d up to %2:d for field %0:s')]
    FInternal_Rate: Integer;


All fields will be proper validated according to the validation attributes applied. Name will be required, Email must be a valid address and FInternal_Rate value must be between 1 and 10. With a few lines you will guarantee that the entity will be persisted with a valid state.

Validation will also help you with your API and GUI. Note how you can provide readable display names and error messages. When using validation in your API build with XData, the API responses will be detailed and informative, and all automatically:

Validation JSON response


And, of course, you can benefit from such information to easily build nice user interfaces informing the user about the validation results. The following screenshot is the same one used for the TMS Auth example above, but displaying results for password validation:

Password validation results


Attribute-based event handlers

Events are an important feature of any framework, and with Aurelius is not different. It provides several events you can use to add custom business logic. You can add specific code just before an entity is being saved, after an entity is deleted, when an SQL is being executed, among others.

The interesting feature coming is that you will now be able to add event handlers directly in your classes, using attributes. This will make your code even more organized, will improve readability and allow you to better follow the single-responsibility principle. It will be as simple as this:

TCustomer = class
  [OnInserting]
  procedure DoSomethingBeforeSave;

  [OnDelete]
  procedure DoSomethingAfterDelete;


Whenever a customer entity is about to be persisted, OnInserting method will be called and you can add any relevant code in that method. You can receive arguments in OnInserting, or you can even use with without them, like in the example above, making you class really independent of 3rd party custom types.

And more events are coming as well, for example, the new data validation mechanism mentioned above will also offer you an OnValidate event, which you can easily use like this:

TCustomer = 
  [OnValidate]
  function CheckBirthday: IValidationResult;

{...}  

  function TCustomer.CheckBirthday: IValidationResult;
  begin
    Result := TValidationResult.Create;

    if YearOf(Birthday) < 1899 then
      Result.Errors.Add(TValidationError
        .Create('A person born in the XIX century is not accepted'));

    if (MonthOf(Birthday) = 8) and (DayOf(Birthday) = 13) then
      Result.Errors.Add(TValidationError
        .Create('A person born on August, 13th is not accepted'));
  end;


That's all...?

I hope you have followed me until here, and I hope you are as excited as us with the upcoming features and and libraries. Yes, that's a lot of things to expect for Delphi and TMS Business in 2021! But I'd like to stress that what's coming is not necessarily limited to what we put here. There might be even more! (Things we cannot disclose right now).

Did you like the news? Please comment below, let us know what you think and what are your opinions and expectations on this. And don't forget to subscribe to our news channels to be informed when things are released and for many other exciting news from TMS: subscribe to our e-mail newsletter, follow our Facebook page and subscribe to our YouTube channel!

Update: Want to see these listed features in action? Register for the free webinar "What is coming in TMS BIZ in 2021", to happen on Tuesday, February 23, 2021 3:00:00 PM UTC at the TMS Web Academy!



Wagner Landgraf


Bookmarks: 

This blog post has received 23 comments.


1. Monday, February 15, 2021 at 9:48:38 PM

That is fantastic news! I cannot wait getting my hand on that, those features are looking so nice and will for sure ease our developer life.

I''m also excited working with the new Aurelius version. Any ETA ?


WIERZBICKI Stéphane


2. Monday, February 15, 2021 at 10:29:01 PM

TMS Auth ... excellent news

A complete framework for adding authentication to your application. That''s just what I need right now.
Looking forward to this feature and more.

Thank you

Kamran


3. Monday, February 15, 2021 at 11:17:01 PM

Very good resources ... and migrations, do we have any predictions?

Marco Polo Viana


4. Tuesday, February 16, 2021 at 12:12:59 AM

Every single one of these features are welcomed. But workflow is delightful. Waiting for it a long time and looking to implement it

Elias Eduardo


5. Tuesday, February 16, 2021 at 8:52:46 AM

Greetings from the Czech republic, as for me, TMS Auth is icing on the cake and I cannot wait to see it!

Karel Janecek


6. Tuesday, February 16, 2021 at 11:19:49 AM

Hi,

double, triple, quadruple WOW !!!!

I updated my subscription just a few days ago!!

Great work Wagner! Very great work!


Piffer Claudio


7. Tuesday, February 16, 2021 at 12:46:05 PM

OMG! Looks awesome!


Koistinen Mika


8. Tuesday, February 16, 2021 at 1:03:07 PM

Thank you Stéphane, Kamran, Eduardo, Marco, Karel, Claudio, Mika. I''m glad you liked it! Stéphane: we aim to release an Aurelius update this month (February).

Wagner R. Landgraf


9. Tuesday, February 16, 2021 at 7:57:41 PM

Awesome ! Can''t wait !! So many great features !!

Farias Anderson


10. Wednesday, February 17, 2021 at 1:59:01 AM

TMS Auth -- YAY! Exactly what I''ve been looking for. Will it be an additional thing added to the Biz Suite? Or just another library or something in the IDE? Do you know yet?

Also, I''m not quite clear what you''re alluding to with the term "multi-tenancy". Can you point to an explanation of it somewhere? (From the discussion here, it suggests a few different things to me.)

Schwartz David


11. Wednesday, February 17, 2021 at 11:51:04 AM

bloody magic!

Russell Weetch


12. Wednesday, February 17, 2021 at 12:06:31 PM

Thanks Anderson, Russell! David: It will be a new framework that depends on Aurelius and XData. About multitenancy: https://en.wikipedia.org/wiki/Multitenancy

Wagner R. Landgraf


13. Wednesday, February 17, 2021 at 3:06:02 PM

GraphQL is a much awaited feature. I wonder if it will be able to automatically create the Schema based on Aurelius mappings just like XData. So that one can Query any entities (with its relationships) without having to implement Resolvers one by one.

Congrats Wagner/TMS for the great work.

Farias Anderson


14. Wednesday, February 17, 2021 at 3:51:38 PM

@Anderson: that''s the idea!

Wagner R. Landgraf


15. Wednesday, February 17, 2021 at 5:44:10 PM

Sweet! Can''t wait for the Webinar

Farias Anderson


16. Wednesday, February 17, 2021 at 7:20:29 PM

Somewhat of an OT question: all of these services need to run on a server somewhere. For testing it can be on your main computer or one on an internal network. But for live / production use, they need to be on a real server somewhere that may be accessible to anyone.

One topic I''ve never seen discussed is things that need to be taken into consideration for such an environment. I''ve had Linux-based web servers for 25 years, and they get hacked regularly. It''s not something I enjoy having to deal with. Everywhere I''ve worked, we''ve had an IT Dept that thankfully handles this stuff so I can focus on my code. But it would be nice to see an article discussing things to consider when looking at selecting a hosting environment, especially if the code is Windows-based.

I look at my raw web logs from time to time (on Linux servers) and they''re flooded with calls from script kiddies trying to access folders that are commonly defined in Windows environments, which has always been one reason I prefer Linux for everything web-related. (Most of the hackers seem to get in through holes in Wordpress plugins, the best I can tell.)

I''d like to see a little guidance as far as how to safely host the services these tools create, and anything we can do to keep them safe from hackers. Maybe it''s a topic for the Web Academy?

Schwartz David


17. Wednesday, February 17, 2021 at 7:31:21 PM

David, there are a gazillion of articles all over the internet about server security. But if you feel to discuss this deeper, I suggest you post to our Support Center: https://support.tmssoftware.com

Wagner R. Landgraf


18. Wednesday, February 17, 2021 at 10:01:11 PM

Sweet! Can''t wait for the Webinar

Farias Anderson


19. Thursday, February 18, 2021 at 4:48:25 AM

Great news! Authorization in XDATA is a must have! New BPM workflow engine sounds very interesting and excited to test when ready. GraphQL integrated with XDATA would be fantastic! Will try to attend the upcoming Biz 2021 webminar.

Great job!

Tecun Beto


20. Thursday, February 18, 2021 at 6:09:29 PM

Great news !
BPM support and Multi Tenancy !
Would like to know more for BPM !


DAVE


21. Friday, February 19, 2021 at 5:16:32 PM

Thanks Bet and Dave. Stay tuned, subscribe our channels, and if you have a more specific direct question, get in touch with us via our support channels!

Wagner R. Landgraf


22. Wednesday, March 3, 2021 at 10:06:51 PM

I will start a project and will use TMS products. After i read this post i feel better. Thanks to TMS for great products.

Ramazan Geven


23. Wednesday, March 3, 2021 at 10:21:47 PM

Thank you, Ramazan, and welcome!

Wagner R. Landgraf




Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post