Осенью я написал на Delphi небольшой REST-сервис для обмена данными с информационной системой другой компании. По регламенту информационного взаимодействия ответ на HTTP-запрос с ошибкой должен быть в формате JSON:
1. При вызове несуществующего метода:
Пусть вас не смущает, что для GET-метода у меня в API используется метод POST – это требование регламента взаимодействия. Вероятно, что в компании, сочинившей регламент, знают только этот метод. С другой стороны, для REST API не существует официального стандарта, поэтому можно делать как захочется.
2. При вызове метода с не правильным паролем: Как вы видите, эти ответы совсем не подходят под требования регламента. Что бы исправить это нам необходимо добавить собственный обработчик ошибок и в нем сформировать правильный ответ. Собственный обработчик ошибок в DelphiMVCFramework – это процедура:
1. При вызове несуществующего метода: 2. При вызове метода с не правильным паролем: DelphiMVCFramework - RESTful, JSON-RPC и ActiveRecord фреймворк для разработки на Delphi.
Для начала приведу примеры ответов моего сервиса, которые возвращал сам DelphiMVCFramework:{ "error_code": код ошибки, "error_name": "текст ошибки" }
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 уже реализованы. Посмотрите демки.
Удалить