Even if the response format is a JSON object by default, and expected as such by our TServiceContainerClient implementation, there is a way of returning any content from a remote request. It may be used by AJAX or HTML applications to return any kind of data, i.e. not only JSON results, but pure text, HTML or even binary content. Our TServiceFactoryClient instance is also able to handle such requests, and will save client-server bandwidth when transmitting some BLOB data (since it won't serialized the content with Base64 encoding).

In order to specify a custom format, you can use the following TServiceCustomAnswer record type as the result of an interface function:

  TServiceCustomAnswer = record
    Header: RawUTF8;
    Content: RawByteString;
  end;

The Header field shall be not null (i.e. not equal to ''), and contains the expected content type header (e.g. TEXT_CONTENT_TYPE_HEADER or HTML_CONTENT_TYPE_HEADER). Then the Content value will be transmitted back directly to the client, with no JSON serialization. Of course, no var nor out parameter will be transmitted either (since there is no JSON result array any more).

In order to implement such method, you may define such an interface:

  IComplexCalculator = interface(ICalculator)
    ['{8D0F3839-056B-4488-A616-986CF8D4DEB7}']
    function TestBlob(n: TComplexNumber): TServiceCustomAnswer;
  end;

Which may be implemented for instance as such:

function TServiceComplexCalculator.TestBlob(n: TComplexNumber): TServiceCustomAnswer;
begin
  Result.Header := TEXT_CONTENT_TYPE_HEADER;
  Result.Content := FormatUTF8('%,%',[n.Real,n.Imaginary]);
end;

This will return not a JSON object, but a plain TEXT content.

Regression tests will make the following process:

  with CC.TestBlob(C3) do begin
    Check(Header=TEXT_CONTENT_TYPE_HEADER);
    Check(Content=FormatUTF8('%,%',[C3.Real,C3.Imaginary]));
  end;

Note that since there is only one BLOB content returned, no var nor out parameters are allowed to be defined for this method. If this is the case, an exception will be raised during the interface registration step. But you can define any const parameter needed, to specify your request.

You may also be able to use this feature to implement custom UTF-8 HTML creation, setting the Header value to HTML_CONTENT_TYPE_HEADER constant, in conjunction with rmREST mode and URI-encoded parameters.

Continue reading...

This article is part of a list of other blog articles, extracted from the official Synopse mORMot framework documentation:

Feedback and questions are welcome on our forum, just as usual.