Осенью я написал на Delphi небольшой REST-сервис для обмена данными с информационной системой другой компании. По регламенту информационного взаимодействия ответ на HTTP-запрос с ошибкой должен быть в формате JSON:
1. При вызове несуществующего метода:
Пусть вас не смущает, что для GET-метода у меня в API используется метод POST – это требование регламента взаимодействия. Вероятно, что в компании, сочинившей регламент, знают только этот метод. С другой стороны, для REST API не существует официального стандарта, поэтому можно делать как захочется.
2. При вызове метода с не правильным паролем: Как вы видите, эти ответы совсем не подходят под требования регламента. Что бы исправить это нам необходимо добавить собственный обработчик ошибок и в нем сформировать правильный ответ. Собственный обработчик ошибок в DelphiMVCFramework – это процедура:
1. При вызове несуществующего метода: 2. При вызове метода с не правильным паролем: DelphiMVCFramework - RESTful, JSON-RPC и ActiveRecord фреймворк для разработки на Delphi.
{
"error_code": код ошибки,
"error_name": "текст ошибки"
}
Для начала приведу примеры ответов моего сервиса, которые возвращал сам DelphiMVCFramework:1. При вызове несуществующего метода:
Пусть вас не смущает, что для GET-метода у меня в API используется метод POST – это требование регламента взаимодействия. Вероятно, что в компании, сочинившей регламент, знают только этот метод. С другой стороны, для REST API не существует официального стандарта, поэтому можно делать как захочется.
2. При вызове метода с не правильным паролем: Как вы видите, эти ответы совсем не подходят под требования регламента. Что бы исправить это нам необходимо добавить собственный обработчик ошибок и в нем сформировать правильный ответ. Собственный обработчик ошибок в DelphiMVCFramework – это процедура:
TMVCExceptionHandlerProc = reference to procedure(E: Exception; SelectedController: TMVCController; WebContext: TWebContext; var ExceptionHandled: Boolean);которая устанавливается, как обработчик ошибок для экземпляра объекта TMVCEngine. В примере к библиотеке "custom_exception_handling" это сделано так:
type
TMyWebModule = class(TWebModule)
...
private
FMVC: TMVCEngine;
end;
...
procedure TMyWebModule.WebModuleCreate(Sender: TObject);
var
lExceptionHandler: TMVCExceptionHandlerProc;
begin
lExceptionHandler := procedure(
E: Exception;
SelectedController: TMVCController;
WebContext: TWebContext;
var ExceptionHandled: Boolean)
var
lColor: string;
begin
if E is EMyException then
begin
case EMyException(E).Severity of
Fatal, Error:
lColor := 'red';
Warning:
lColor := 'yellow';
Information:
lColor := 'blue';
else
lColor := 'black';
end;
WebContext.Response.ContentType := TMVCMediaType.TEXT_HTML;
WebContext.Response.Content :=
'<html><body><h1>Error occurred</h1>' +
Format('<h2 style="color: %s">', [lColor]) +
TNetEncoding.HTML.Encode(EMyException(E).ToString) +
'</h2>' + '<p>your truly custom exception handler...</p>' +
'</body></html>';
ExceptionHandled := True;
end
else if E is EMVCException then
begin
WebContext.Response.ContentType := TMVCMediaType.TEXT_HTML;
WebContext.Response.Content :=
'<html><body><h1>Error occurred</h1>' +
Format('<h2 style="color: red">', [lColor]) +
TNetEncoding.HTML.Encode(E.Message) + '</h2>' +
'<p>your truly custom exception handler...</p>' +
'</body></html>';
ExceptionHandled := True;
end;
end;
FMVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
...
end);
FMVC.SetExceptionHandler(lExceptionHandler);
Моя реализация процедуры обработчика ошибок выглядит так:
procedure ExceptionHandlerProc(E: Exception; SelectedController: TMVCController;
WebContext: TWebContext; var ExceptionHandled: Boolean);
procedure CreateResponse(const iErrorCode: Integer; const sErrorName: String);
var
jo: TJSONObject;
begin
WebContext.Response.StatusCode := iErrorCode;
jo := TJSONObject.Create;
try
jo.AddPair('error_code', TJSONNumber.Create(iErrorCode));
jo.AddPair('error_name', sErrorName);
WebContext.Response.Content := jo.ToString;
finally
jo.Free
end;
end;
begin
WebContext.Response.ContentType := TMVCMediaType.APPLICATION_JSON;
if E is EXyzException
then CreateResponse(EXyzException(E).Code, EXyzException(E).LogMessage)
else if E is EMVCException
then CreateResponse(EMVCException(E).HttpErrorCode, E.Message)
else CreateResponse(500, E.Message);
ExceptionHandled := True;
end;
Теперь посмотрим содержимое ответов моего сервиса с ее использованием:1. При вызове несуществующего метода: 2. При вызове метода с не правильным паролем: DelphiMVCFramework - RESTful, JSON-RPC и ActiveRecord фреймворк для разработки на Delphi.




А чем DelphiMVCFramework удобнее того же банального TIdHTTPServer?
ОтветитьУдалитьУ TIdHTTPServer надо самому допиливать многие плюшки, которые в DMVCF уже реализованы. Посмотрите демки.
Удалить