2020-08-18 23:19:17 +02:00
|
|
|
|
// ***************************************************************************
|
|
|
|
|
//
|
|
|
|
|
// Delphi MVC Framework
|
|
|
|
|
//
|
|
|
|
|
// Copyright (c) 2010-2020 Daniele Teti and the DMVCFramework Team
|
|
|
|
|
//
|
|
|
|
|
// https://github.com/danieleteti/delphimvcframework
|
|
|
|
|
//
|
|
|
|
|
// Collaborators on this file:
|
|
|
|
|
// Jo<4A>o Ant<6E>nio Duarte (https://github.com/joaoduarte19)
|
|
|
|
|
//
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
//
|
|
|
|
|
// *************************************************************************** }
|
|
|
|
|
|
2020-08-04 00:48:35 +02:00
|
|
|
|
unit MVCFramework.RESTClient.Intf;
|
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
{$I dmvcframework.inc}
|
|
|
|
|
|
2020-08-04 00:48:35 +02:00
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
uses
|
|
|
|
|
System.Classes,
|
2020-08-09 02:18:36 +02:00
|
|
|
|
System.SysUtils,
|
|
|
|
|
MVCFramework.Serializer.Intf,
|
2020-08-18 23:19:17 +02:00
|
|
|
|
MVCFramework.Serializer.Commons,
|
2020-08-09 02:18:36 +02:00
|
|
|
|
REST.Types,
|
|
|
|
|
Data.DB,
|
2020-08-21 02:45:51 +02:00
|
|
|
|
System.TypInfo,
|
|
|
|
|
System.Net.HttpClient;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
|
|
|
|
type
|
2020-08-18 23:19:17 +02:00
|
|
|
|
IMVCRESTResponse = interface;
|
2020-08-09 02:18:36 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
IMVCRESTClient = interface
|
2020-08-04 00:48:35 +02:00
|
|
|
|
['{592BC90F-B825-4B3B-84A7-6CA3927BAD69}']
|
|
|
|
|
|
|
|
|
|
function BaseURL: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function BaseURL(const aBaseURL: string): IMVCRESTClient; overload;
|
2020-08-21 02:45:51 +02:00
|
|
|
|
function BaseURL(const aHost: string; const aPort: Integer): IMVCRESTClient; overload;
|
|
|
|
|
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function RaiseExceptionOn500: Boolean; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function RaiseExceptionOn500(const aRaiseExceptionOn500: Boolean): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
|
|
|
|
function ProxyServer: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function ProxyServer(const aProxyServer: string): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
function ProxyPort: Integer; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function ProxyPort(const aProxyPort: Integer): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
function ProxyUsername: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function ProxyUsername(const aProxyUsername: string): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
function ProxyPassword: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function ProxyPassword(const aProxyPassword: string): IMVCRESTClient; overload;
|
|
|
|
|
|
2020-08-20 20:08:41 +02:00
|
|
|
|
function UserAgent: string; overload;
|
|
|
|
|
function UserAgent(const aUserAgent: string): IMVCRESTClient; overload;
|
|
|
|
|
|
2020-08-21 02:45:51 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Clears all parameters, except authorization headers. This method is executed after each request is completed.
|
|
|
|
|
/// </summary>
|
2020-08-20 20:08:41 +02:00
|
|
|
|
function ClearAllParams: IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get request timeout.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Timeout: Integer; overload;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Set request timeout.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Timeout(const aTimeout: Integer): IMVCRESTClient; overload;
|
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add basic authorization header. Authorization = Basic <Username:Password>
|
|
|
|
|
/// </summary>
|
|
|
|
|
function SetBasicAuthorization(const aUsername, aPassword: string): IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add bearer authorization header. Authorization = Bearer <Token>
|
|
|
|
|
/// </summary>
|
|
|
|
|
function SetBearerAuthorization(const aToken: string): IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2020-08-20 20:08:41 +02:00
|
|
|
|
/// Add a header.
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aName">
|
|
|
|
|
/// Header name
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aValue">
|
|
|
|
|
/// Header value
|
|
|
|
|
/// </param>
|
2020-08-20 20:08:41 +02:00
|
|
|
|
/// <param name="aDoNotEncode">
|
|
|
|
|
/// Indicates whether the value of this header should be used as is (True), or encoded by the component (False)
|
|
|
|
|
/// </param>
|
|
|
|
|
function AddHeader(const aName, aValue: string; const aDoNotEncode: Boolean = False): IMVCRESTClient; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Clears all headers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function ClearHeaders: IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a cookie header.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function AddCookie(const aName, aValue: string): IMVCRESTClient;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Clear all cookie headers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function ClearCookies: IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a URL segment parameter. The parameters of your url path may be enclosed in braces or in
|
|
|
|
|
/// parentheses starting with a money sign. <c>/api/{param1}/($param2)</c>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aName">
|
|
|
|
|
/// Parameter name
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aValue">
|
|
|
|
|
/// Parameter value
|
|
|
|
|
/// </param>
|
|
|
|
|
function AddPathParam(const aName, aValue: string): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: Integer): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: Int64): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: TGUID): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: TDateTime): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: TDate): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: TTime): IMVCRESTClient; overload;
|
|
|
|
|
function AddPathParam(const aName: string; aValue: Double): IMVCRESTClient; overload;
|
|
|
|
|
function ClearPathParams: IMVCRESTClient;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a QueryString parameter. <c>/api/person?para1=value&param2=value</c>
|
|
|
|
|
/// </summary>
|
|
|
|
|
function AddQueryStringParam(const aName, aValue: string): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: Integer): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: Int64): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: TGUID): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: TDateTime): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: TDate): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: TTime): IMVCRESTClient; overload;
|
|
|
|
|
function AddQueryStringParam(const aName: string; aValue: Double): IMVCRESTClient; overload;
|
|
|
|
|
function ClearQueryParams: IMVCRESTClient;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
|
|
|
|
function Accept: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function Accept(const aAccept: string): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
function AcceptCharset: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function AcceptCharset(const aAcceptCharset: string): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
function AcceptEncoding: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function AcceptEncoding(const aAcceptEncoding: string): IMVCRESTClient; overload;
|
2020-08-20 20:08:41 +02:00
|
|
|
|
function HandleRedirects: Boolean; overload;
|
|
|
|
|
function HandleRedirects(const aHandleRedirects: Boolean): IMVCRESTClient; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get the current resource path.
|
|
|
|
|
/// </summary>
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function Resource: string; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Set the current resource path.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Resource(const aResource: string): IMVCRESTClient; overload;
|
2020-08-20 23:35:28 +02:00
|
|
|
|
|
|
|
|
|
function URLAlreadyEncoded: Boolean; overload;
|
|
|
|
|
function URLAlreadyEncoded(const aURLAlreadyEncoded: Boolean): IMVCRESTClient; overload;
|
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a body to the requisition.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aBody">
|
|
|
|
|
/// Body in string format.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aContentType">
|
|
|
|
|
/// Body content type.
|
|
|
|
|
/// </param>
|
2020-08-20 20:08:41 +02:00
|
|
|
|
function AddBody(const aBody: string; const aDoNotEncode: Boolean = False;
|
|
|
|
|
const aContentType: TRESTContentType = TRESTContentType.ctNone): IMVCRESTClient; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a body to the requisition
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aBodyStream">
|
|
|
|
|
/// Body in Stream format
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aContentType">
|
|
|
|
|
/// Body content type
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aOwnsStream">
|
|
|
|
|
/// If OwnsStream is true, Stream will be destroyed by IMVCRESTClient.
|
|
|
|
|
/// </param>
|
2020-08-20 20:08:41 +02:00
|
|
|
|
function AddBody(aBodyStream: TStream; const aContentType: TRESTContentType = TRESTContentType.ctNone;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
const aOwnsStream: Boolean = True): IMVCRESTClient; overload;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Add a body to the requisition
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aBodyObject">
|
|
|
|
|
/// Body in Object format. The object will be serialized to a JSON string.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aOwnsObject">
|
|
|
|
|
/// If OwnsObject is true, BodyObject will be destroyed by IMVCRESTClient.
|
|
|
|
|
/// </param>
|
|
|
|
|
function AddBody(aBodyObject: TObject; const aOwnsObject: Boolean = True): IMVCRESTClient; overload;
|
|
|
|
|
function ClearBody: IMVCRESTClient;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds a file as the request body. Several files can be added in the same request. In this case the request
|
|
|
|
|
/// will be of the multipart/form-data type
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aName">
|
|
|
|
|
/// Field name
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aFileName">
|
|
|
|
|
/// File path
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aContentType">
|
|
|
|
|
/// File content type
|
|
|
|
|
/// </param>
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function AddFile(const aName, aFileName: string;
|
2020-08-20 20:08:41 +02:00
|
|
|
|
const aContentType: TRESTContentType = TRESTContentType.ctNone): IMVCRESTClient; overload;
|
|
|
|
|
function AddFile(const aFileName: string;
|
|
|
|
|
const aContentType: TRESTContentType = TRESTContentType.ctNone): IMVCRESTClient; overload;
|
2020-08-18 23:19:17 +02:00
|
|
|
|
function ClearFiles: IMVCRESTClient;
|
2020-08-20 20:08:41 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the next request asynchronously.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="aCompletionHandler">
|
|
|
|
|
/// An anonymous method that will be run after the execution completed.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aSynchronized">
|
|
|
|
|
/// Specifies if aCompletioHandler will be run in the main thread's (True) or execution thread's (False) context.
|
|
|
|
|
/// </param>
|
|
|
|
|
/// <param name="aCompletionHandlerWithError">
|
|
|
|
|
/// An anonymous method that will be run if an exception is raised during execution.
|
|
|
|
|
/// </param>
|
2020-08-21 02:45:51 +02:00
|
|
|
|
function Async(aCompletionHandler: TProc<IMVCRESTResponse>; aCompletionHandlerWithError: TProc<Exception> = nil;
|
|
|
|
|
const aSynchronized: Boolean = True): IMVCRESTClient;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Execute a Get request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Get: IMVCRESTResponse; overload;
|
|
|
|
|
function Get(const aResource: string): IMVCRESTResponse; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Execute a Post request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Post: IMVCRESTResponse; overload;
|
|
|
|
|
function Post(const aResource: string; const aBody: string = ''): IMVCRESTResponse; overload;
|
|
|
|
|
function Post(const aResource: string; aBody: TObject; const aOwnsBody: Boolean = True): IMVCRESTResponse; overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Execute a Patch request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Patch: IMVCRESTResponse; overload;
|
|
|
|
|
function Patch(const aResource: string; const aBody: string = ''): IMVCRESTResponse; overload;
|
|
|
|
|
function Patch(const aResource: string; aBody: TObject; const aOwnsBody: Boolean = True): IMVCRESTResponse;
|
|
|
|
|
overload;
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Execute a Put request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Put: IMVCRESTResponse; overload;
|
|
|
|
|
function Put(const aResource: string; const aBody: string = ''): IMVCRESTResponse; overload;
|
|
|
|
|
function Put(const aResource: string; aBody: TObject; const aOwnsBody: Boolean = True): IMVCRESTResponse; overload;
|
2020-08-09 02:18:36 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Execute a Delete request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function Delete: IMVCRESTResponse; overload;
|
|
|
|
|
function Delete(const aResource: string): IMVCRESTResponse; overload;
|
2020-08-09 02:18:36 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Serialize the current dataset record and execute a POST request.
|
|
|
|
|
/// </summary>
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function DataSetInsert(const aResource: string; aDataSet: TDataSet; const aIgnoredFields: TMVCIgnoredList = [];
|
2020-08-18 23:19:17 +02:00
|
|
|
|
const aNameCase: TMVCNameCase = ncAsIs): IMVCRESTResponse;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Serialize the current dataset record and execute a PUT request.
|
|
|
|
|
/// </summary>
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function DataSetUpdate(const aResource: string; aDataSet: TDataSet; const aIgnoredFields: TMVCIgnoredList = [];
|
2020-08-18 23:19:17 +02:00
|
|
|
|
const aNameCase: TMVCNameCase = ncAsIs): IMVCRESTResponse;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Delete the current dataset record by executing a delete request.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function DataSetDelete(const aResource: string): IMVCRESTResponse;
|
2020-08-09 02:18:36 +02:00
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Register a custom serializer to the RESTClient serializer.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function RegisterTypeSerializer(const aTypeInfo: PTypeInfo; aInstance: IMVCTypeSerializer): IMVCRESTClient;
|
2020-08-20 23:35:28 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new instance of RESTClient with all parameters of the current RESTClient.
|
|
|
|
|
/// </summary>
|
|
|
|
|
function CloneRESTClient: IMVCRESTClient;
|
2020-08-09 02:18:36 +02:00
|
|
|
|
end;
|
|
|
|
|
|
2020-08-18 23:19:17 +02:00
|
|
|
|
IMVCRESTResponse = interface
|
2020-08-09 02:18:36 +02:00
|
|
|
|
['{BF611B46-CCD1-47C7-8D8B-82EA0518896B}']
|
2020-08-04 00:48:35 +02:00
|
|
|
|
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function Success: Boolean;
|
|
|
|
|
function StatusCode: Integer;
|
|
|
|
|
function StatusText: string;
|
|
|
|
|
function ErrorMessage: string;
|
|
|
|
|
function Headers: TStrings;
|
2020-08-21 02:45:51 +02:00
|
|
|
|
{$IF defined(SYDNEYORBETTER)}
|
|
|
|
|
function Cookies: TCookies;
|
|
|
|
|
{$ENDIF}
|
2020-08-09 02:18:36 +02:00
|
|
|
|
function HeaderByName(const aName: string): string;
|
|
|
|
|
function Server: string;
|
|
|
|
|
function FullRequestURI: string;
|
|
|
|
|
function ContentType: string;
|
|
|
|
|
function ContentEncoding: string;
|
|
|
|
|
function ContentLength: Integer;
|
|
|
|
|
function Content: string;
|
|
|
|
|
function RawBytes: TBytes;
|
|
|
|
|
procedure SaveContentToStream(aStream: TStream);
|
|
|
|
|
procedure SaveContentToFile(const aFileName: string);
|
2020-08-04 00:48:35 +02:00
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
|
|
end.
|