Showing posts with label rest. Show all posts
Showing posts with label rest. Show all posts

Thursday, May 28, 2020

Delphi 10.4 Sydney is here!

Hi folks,

Delphi 10.4 Sydney has just released and this version comes with a lot of interesting features:

    • New Delphi CodeInsight based on LSP server
    • Custom Managed Records in the Delphi Language
    • New VCL Components, including TEdgeBrowser, and expanded High DPI support for VCL styled applications
    • Enhanced Delphi multi-device platform support integrating newer Apple APIs and supporting the latest Android
    • New LLDB-based debugger for Windows 64-bit for C++
    • Unified installer for online & offline installations
    • GetIt Package Manager Enhancements


            I would like to spend few words around the features that impressed me:


            Code Insight Technology in Delphi 10.4

            From David Millington blog post:

            In 10.4, Code insight features are implemented using a ‘LSP Server’. LSP refers to the Language Server Protocol, which is a standardized way to implement code insight-like features for many languages. An IDE talks to a ‘language server’, which is a small helper app that calculates and generates the information the IDE displays. It does so using a defined protocol, and that’s the language server protocol.

            In other words, the IDE now talks to a helper app when you do something like open a project, or type a keystroke in your file.

            What does it means?
            • Communication with another process is asynchronous
            • The work is done in another process
              • This means all the memory usage for calculating results is no longer in the IDE itself. The IDE has more memory, and the helper app can use its entire memory space dedicated solely to providing results
            • What you see onscreen is what the compiler sees. 
              • If your code compiles, you won’t see any Error Insight errors; conversely, if you do see red squiggly underlines in your code or in the Structure view, your code will not compile.
            • You can get code completion while debugging.

            If you want to know more about it have a look to David Millington post 


            Custom Managed Records 

            This is absolutely the top new language feature of Delphi 10.4!

            Now in 10.4 the Delphi record type supports custom initialization and finalization:

            From Marco Cantù blog post:

            You can declare a record with custom initialization and finalization code regardless of the data type of its fields, and you can write such custom initialization and finalization code.
            This is achieved by adding specific, new operators to the record type (you can have one without the other if you want).
            Below is a simple code snippet:

            type
              TMyRecord = record
                Value: Integer;
                class operator Initialize (out Dest: TMyRecord);
                class operator Finalize(var Dest: TMyRecord);
              end;


            The huge difference between this construction mechanism and what was previously available for records is the automatic invocation. If you write something like the code below, you can invoke both the initializer and the finalizer, and end up with a try-finally block generated by the compiler for your managed record instance.

            Marco Cantù post to know more.


            GetIt Package Manager Enhancements

            GetIt Package Manager Enhancements in Delphi 10.4:
            • the ability of sorting the list of entries by date, seeing the most recent ones on top
            • for each entry you have already installed, the indication that an updated version is available
            • the ability to list all installed entries that have an update available

            Rad studio patches

            A killer feature of the new GeIt is absolutely the ability to use GetIt to distribute patches, with a specific way to alert customers that a patch is available. There is a new section to the Welcome page to indicate when a patch is available and you have not installed it:


            Here a screenshot of Rad Studio patches in action:

            As you can see there is already a patch available through GetIt, this will completely revolutionize the patches distribution!

            Webinar Delphi 10.4

            Here the link for the launch webinar - https://www.youtube.com/watch?v=-rTLEXLVueQ&feature=youtu.be - Enjoy it!


            Other useful resources 


            As you can see from the info above this is a fantastic release! Enjoy it!


            Sunday, August 27, 2017

            Delphi Event Bus and MVVM

            In last ITDevCon, I held a speech on how to build modern applications with Delphi. In the speech I showed what are the good programming techniques and how to reach them in Delphi. The path was completed by presenting the MVVM pattern as solution. For more info about this pattern I suggest you these books:

            1. John Kouraklis, MVVM in Delphi
            2. Syromiatnikov, A., A Journey Through the Land of Model-View-* Design Patterns.

            MVVM intents is to separate the domain logic from the presentation logic in three modules with distinct responsibilities:

            • handle the domain data (Model)
            • View state and business logic (View Model) 
            • Handle user interaction and rendering of the visual user interface (View)
            The hardest part ( as in any software development ) is the Separation of Concerns (SOC), to keep separate layers so future changes do not interfere with each other. High cohesion and loose coupling, precisely! 
            MVVM can manage UI Synchronization in two ways:
            1. Flow synchronization
              • uses direct calls between user interface components and domain. It is based on sequential command: read user input from text box A, processing it with method B, and write the result to text label C 
            2. Observer synchronization
              • the domain layer must implement a notification mechanism to which components of the user interface layer can subscribe. This allows the user interface components to update the state of the user interface when relevant changes in the domain occur
            Both solutions keep the layers separated, but the Flow synchronization forces you to write an enormity of boiler plate code and write an Observer framework from zero ( why reinvent the wheel ? ) would be expensive in terms of developments.
            Delphi Event Bus comes in our help! For those that doesn't know Delphi Event Bus (for short DEB), it is a publish/subscribe Event Bus framework for the Delphi platform.
            DEB is designed to decouple different parts/layers of your application while still allowing them to communicate efficiently.
            Simply put the Subscribe attribute on your subscriber method you are able to receive a specific event, and by specifying the TThreadMode in attribute you can choose the context where to deliver the event.
            For example, if you have to interact with the UI EventBus can deliver events in the main thread or If your subscriber does long running tasks (HTTP request), EventBus can also use background threads to avoid UI blocking. Regardless where an event was posted the EventBus will manage Thread synchronization, so you can deliver an Event in the MainThread and the subscriber will receive it on a background thread and viceversa.
            Look this demo (you need DMVC for server side part) to check how I resolve UI Synchronization in client/server context with REST request in background!









            Tuesday, April 11, 2017

            Delphi and Firebase: Remote configuration

            Hi all,
            as you know Firebase is a backend service that include a data storage service. One of common example of this kind of service is Remote Configuration, that allows you to change the behavior or appearance of your app (ex. change the welcome message of your app) without changing the app source code.
            I've just updated the Firebase4Delphi repository with a new demo : RemoteConfigDemo.
            In this demo I implemented a mechanism to allow to change the behavior and appearance of your app without publishing an app update.
            The process is very simple, you have to:
            1. create a JSON Object in your console project that represents the app configuration
            2. Wraps that configuration in your app
            3. Check when configuration change and communicate it to your app
            In this demo you have the possibilities to change the style of your application, according to OS, at run time.

            Firebase Console 

            AquaGraphite.style configured at run-time
            RubyGraphite.style configured at run-time




            ASAP I'll post a short video to show the power of this feature.

            Saturday, June 18, 2016

            Simple chat messaging system with Delphi and Firebase

            Hi all,
            some time ago I posted about my open source project: Firebase4Delphi. Well, Firebase was acquired by Google and in Google I/O 2016 was showed very interesting news and new features (more info here ). My project provide a REST facade to consume FIREBASE RealTime Database API.
            The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. When you build cross-platform apps with our iOS, Android, and JavaScript SDKs, all of your clients share one Realtime Database instance and automatically receive updates with the newest data. - Firebase Realtime Database Documentation
            In my project there is a sample application about a Chat messaging system. If you enjoy Firebase program (https://console.firebase.google.com/), you are able to create your first Firebase project! See the online documentation to undestand how Firebase works.
            Once you create your application you can start to use the Chat Messaging sample, it's very easy if you follow these steps:
            1. Create a clone of Firebase4Delphi project (or download it)
            2. Open Firebase4DelphiChatDemo.dproj
            3. Deploy the app on your favorite Target Platoform (Windows, Mac, Android, iOS)
            4. Once application started, put in the settings tab (Fig 1) the URL provided by Firebase Realtime Database related to your project (Fig 2) , adding the demo name "chatdemo" as REST parameter
            5. Choose a username
            6. Click Start Chat button
            Fig 1:

            Fig 2:

















            Monday, June 1, 2015

            Firebase4Delphi - A new open source project

            Hi all,
            I have just started a new open source project on github: Firebase4Delphi. For those that don't know Firebase, it's a backend service: including data storage, user authentication, static hosting, and more. Go here for more info https://www.firebase.com/ . The purpose of this project is provide a REST wrapper (facade) to consume FIREBASE REST API. For now there is a client for basically interact with REST API and a ChatDemo example based on the official demo (https://www.firebase.com/tutorial/#session/sf2ovtgq4ko). The project use System.Net library, so is compatible from DelphiXE8. Anyone wants to enjoy this project is welcome!

            Monday, January 19, 2015

            RESTAdapter: a new amazing feature in Delphi MVC Framework

            RESTAdapter is a new amazing feature of the famous Delphi MVCFramework (DMVCFramework for short). DMVCFramework (as you know) is a powerful framework for web solution in Delphi that respect the MVC pattern and reach RMM Level 3! Above there is a link to the site project (if you want more info about this wonderful framework). Ok, let's go ahead. What is RESTAdapter? RESTAdapter turn a Delphi Interface into your REST API. In practice you can declare an interface that represents your REST API and the RESTAdapter does all work for you. Below a mini guide on how it works:
              
            
              [Headers('User-Agent', 'RESTAdapter-Test')]
               IRESTAPIService = interface(IInvokable)
                ['{58B9FA23-92F4-4B8E-814B-05232F32A41F}']
            
                [RESTResource(HttpGet, '/persons')]
                [MapperListOf(TPerson)]
                function GetListPerson: TObjectList<tperson>;
            
                [RESTResource(HttpGet, '/persons/{personid}')]
                function GetPersonByID([Param('personid')] APersonID: integer): TPerson;
            
                [RESTResource(httpPOST, '/persons')]
                function SavePerson([Body] ABody: TPerson): TPerson;
            
              end;
            

            The RestAdapter class generates an implementation of the IRESTAPIService
            interface:

              
              RESTAdapter := TRESTAdapter<IRESTAPIService>.Create; 
              RESTAPIService := RESTAdapter.Build('localhost', 9999);
              Person := RESTAPIService.GetPersonByID(1);
            

            Use RTTI Attributes to describe the REST request:
            • RESTResource: to describe URI and REST verb of resource
            • Headers: a key-value pair that represents a Header of HTTP request
            • MapperListOf: to specify the Object Type of the List
            • Param: to specify that a method parameter is a param of HTTP Request
            • Body: to specify that a method parameter is the body of HTTP Request
            The TRESTAdapter class inherits from TVirtualInterface. TVirtualInterface doesn't behave like an ordinary class, each instance has an associated reference counter to automatically free itself. In practice there isn't need to free the RESTAdapter object.

            In the DMVCFramework samples folder, in particularly "wincellarclientRESTAdapter" you can find a real work example. 

            I hope you enjoy it! 

            Tuesday, June 3, 2014

            Access Marvel Developer API with Delphi XE6



            Marvel has recent made available The Marvel Comics API, that allows developers everywhere to access information about Marvel Universe. "The Marvel Comics API is a RESTful service which provides methods for accessing specific resources at canonical URLs and for searching and filtering sets of resources by various criteria. All representations are encoded as JSON objects".



            So my idea is to access these API with the Delphi REST Client Library and create an awesome app.
            Let's start!
            At First we need to register to the developers program, once registered we will be given 2 keys one public and the other private that will be used to call the Marvel API. For more information about the service, resources, authentication and so on I refer you to the official Pages: General Info - Getting Started - Interactive API tester.
            You can access six resource types using the API:

            • Comics
            • Comic Series
            • Comic Stories
            • Comic events and crossovers
            • Creators
            • Characters

            In this first demo app I get information only about characters of Marvel Universe.




            I created an HeaderFooter Mobile Application by the wizard, modified the text of prebuilt label for the Title ("Marvel Character"), added a TLabel for the name of the Character, a TImage that is the representative image for the character and finally I insert the mainly 3 components of the REST Client Library: RESTClient, RESTRequest and RESTResponse.
            The Marvel Comics API’s base endpoint is http://gateway.marvel.com/v1/public so I put this URL in the BaseURL property of the RESTClient.



            The RESTRequest represent the resource in the REST pattern and in this case represent the character. I defined the Resource property in this way: characters?limit=1&offset={OFFSET}&ts={TS}&apikey={APIKEY}&hash={HASH}.
            There are 3 parameters:
            • limit - that represent the number of the result, in this case 1 result for time because we can see 1 character at time on the form
            • offset - that indicate the distance from the first character
            • ts - a timestamp (or other long string which can change on a request-by-request basis)
            •  apikey - your public key
            • hash - a md5 digest of the ts parameter, your private key and your public key (e.g. md5(ts+privateKey+publicKey)
            This is the snippet code of request:

            procedure THeaderFooterForm.ExecuteRequest;
            var
              TS: string;
              imd5: TIdHashMessageDigest;
              HASHStr: string;
            begin
              // StartWait show a progress dialog until the request is finished
              StartWait;
              TS := IntToStr(DateTimeToUnix(Now));
              RESTRequest1.Params.ParameterByName('OFFSET').Value := FOffSet.ToString;
              RESTRequest1.Params.ParameterByName('TS').Value := TS;
              RESTRequest1.Params.ParameterByName('APIKEY').Value := PUBLIC_KEY;
              imd5 := TIdHashMessageDigest5.Create;
              try
                HASHStr := TS + PRIVATE_KEY + PUBLIC_KEY;
                RESTRequest1.Params.ParameterByName('HASH').Value :=
                  imd5.HashStringAsHex(HASHStr).ToLower;
                RESTRequest1.ExecuteAsync(OnAfterRequest);
              finally
                imd5.Free;
              end;
            end;
            

            Once the call give a result will need to parse the JSON response to take the name of the character and its image, obviously respecting the JSON structure described in the official documentation:

            procedure THeaderFooterForm.OnAfterRequest;
            var
              RetObject: TJSONObject;
              RetData: TJSONObject;
              MResult: TJSONObject;
              Loader: TImageLoaderThread;
              Thumbnail: TJSONObject;
            begin
              try
                RetObject := TJSONObject.ParseJSONValue(RESTResponse1.Content)
                  as TJSONObject;
                RetData := RetObject.GetValue('data') as TJSONObject;
                MResult := (RetData.GetValue('results') as TJSONArray).Get(0)
                  as TJSONObject;
                Thumbnail := MResult.GetValue('thumbnail') as TJSONObject;
                Text1.Text := MResult.GetValue('name').Value;
                // TImageLoaderThread is a custom class to retrieve the image in a background thread
                // and 2 anonymous methods to notify when thread finish download image and when bitmap is ready  
                Loader := TImageLoaderThread.Create(true, nil, OnBitmapLoaded);
                Loader.ImgURL := Thumbnail.GetValue('path').Value + '.' +
                  Thumbnail.GetValue('extension').Value;
                Loader.Start;
              finally
                StopWait;
              end;
            end;
            

            The image is provided by another URL so I have to make another request for the image.
            Both the request (info character + image) are completed by background threads so it doesn't block the GUI.
            Here some screeenshot about final app





            The app run on Android device but the code work on Android, iOS, Windows and Mac.
            In the next post I will improve the app creating a master-detail structure that allowing to search character by other criteria!
            The code was loaded on my github repository.