#1 2014-06-19 23:46:12

avista
Member
Registered: 2014-01-06
Posts: 63

Custom HTTP Status Code in Interface Based Services

As stated here, it seems impossible:

http://synopse.info/forum/viewtopic.php?id=1536

I've been working on a web service API for consumption by others via JavaScript, etc. using Interface Based Services, but without support for custom status codes, the project cannot move forward.

Is there any way at all to return a custom HTTP Status code for Interface Based Services?

In the above post, you said:

By now, it expects HTML_SUCCESS (200) on the client side for any success full process.
See e.g. TServiceFactoryClient.InternalInvoke().

So allowing any custom code may be very difficult, and break the default expected behavior of the JSON-RPC protocol.

Note that if you raise an exception, it will return an error 500 to the client.

I'm wondering how this would break existing code.  Why would it be a problem for the client to continue to require HTML_SUCCESS (200), but fail on a non-200 status code?

I changed the following code in mORMot.pas to enable returning a status code in TServiceCustomAnswer, which seems to work.

Note that if the Status is 0, it will default to HTML_SUCCESS (200).

  TServiceCustomAnswer = record
    Status: Cardinal; // <-----------------
    Header: RawUTF8;
    Content: RawByteString;
  end;
function TServiceMethod.InternalExecute(Instances: array of pointer;
  Par: PUTF8Char; Res: TTextWriter; var aHead: RawUTF8; var aStatus: Cardinal; // <-----------------
  Options: TServiceMethodOptions; ResultAsJSONObject: boolean;
  BackgroundExecutionThread: TSynBackgroundThreadProcedure): boolean;
procedure TServiceFactoryServer.ExecuteMethod(Ctxt: TSQLRestServerURIContext);
[…]
      Ctxt.ServiceResultStart(WR);
      try
        if optExecLockedPerInterface in fExecution[Ctxt.ServiceMethodIndex].Options then
          EnterCriticalSection(fInstanceLock);
        if not fInterface.fMethods[Ctxt.ServiceMethodIndex].InternalExecute(
            [PAnsiChar(Inst.Instance)+entry^.IOffset],Ctxt.ServiceParameters,WR,
             Ctxt.Call.OutHead,Ctxt.Call.OutStatus, // <-----------------
             fExecution[Ctxt.ServiceMethodIndex].Options,
             Ctxt.ForceServiceResultAsJSONObject,
             {$ifdef LVCL}nil{$else}fBackgroundThread{$endif}) then
          exit; // wrong request
      finally
        if optExecLockedPerInterface in fExecution[Ctxt.ServiceMethodIndex].Options then
          LeaveCriticalSection(fInstanceLock);
      end;
      if Ctxt.Call.OutHead='' then begin // <>'' for TServiceCustomAnswer
        Ctxt.ServiceResultEnd(WR,Inst.InstanceID);
        Ctxt.Call.OutHead := JSON_CONTENT_TYPE_HEADER;
        Ctxt.Call.OutStatus := HTML_SUCCESS;  // <-----------------
      end
      else if (Ctxt.Call.OutStatus = 0) then // <-----------------
        Ctxt.Call.OutStatus := HTML_SUCCESS; // <-----------------
      WR.SetText(Ctxt.Call.OutBody);
      // Ctxt.Call.OutStatus := HTML_SUCCESS; // <----------------- commented out
[…]
end;

Does this seem like a viable solution?

Last edited by avista (2014-06-20 06:51:00)

Offline

#2 2014-06-20 14:58:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Custom HTTP Status Code in Interface Based Services

Yes, sounds fine.
I would like to review it before applying the patch.

Could you please add a feature request ticket so that I add this feature?
See http://synopse.info/fossil/tktnew

Offline

#3 2014-06-20 15:33:42

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Custom HTTP Status Code in Interface Based Services

OK - forget the ticket.
I've just implemented it, pretty close to your patch.
See http://synopse.info/fossil/info/cc8721bad1

Finally, the new Status field could be overriden with a propert HTML code, if the default HTML_SUCCESS is not enough for your purpose.
Note that when consumed from Delphi clients, HTML_SUCCESS is expected to be returned by the server: you should customize Status field only for plain AJAX / web clients.

Thanks for the feedback and proposal!

Offline

#4 2014-06-20 16:20:41

avista
Member
Registered: 2014-01-06
Posts: 63

Re: Custom HTTP Status Code in Interface Based Services

Thanks, it is very much appreciated!

Offline

Board footer

Powered by FluxBB