public RestHandlerBaseTests() { this.handler = A.Fake <RestHandlerBase>(options => options.CallsBaseMethods()); this.request = A.Fake <ISydneyRequest>(); // There are no tests for any calls to this because it turns out that // LogInformation, LogWarning, and LogError are extension methods so // they can't be verified usefully. this.logger = NullLogger.Instance; }
// Override the functions for the HTTP methods you want to handle (the rest // will return HTTP 405). protected override async Task <ISydneyResponse> GetAsync(ISydneyRequest request) { dynamic payload = new { books = new[] { "The Fellowship of the Ring", "The Two Towers", "The Return of the King" } }; // Handlers must either return a SydneyResponse or throw an exception. // A SydneyResponse contains an HttpStatusCode and an optional payload // that is serialized as JSON (using Utf8Json) and send back to the client. return(new SydneyResponse(HttpStatusCode.OK, payload)); }
protected override async Task <ISydneyResponse> PostAsync(ISydneyRequest request) { // You can deserialize a request payload by calling request.DeserializePayloadAsync<T>(). // This will deserialize a JSON payload into whatever type you have defined. dynamic payload = await request.DeserializePayloadAsync <dynamic>(); if (payload == null) { // Throwing an HttpResponseException (or subclass) from your handler will // return the specified HttpStatusCode as a response and optionally the // message as a response payload. throw new HttpResponseException(HttpStatusCode.BadRequest, "Payload is null"); } // Throwing any other uncaught exception from your handler will // return HTTP 500 and optionally the message as a response payload. throw new InvalidOperationException("Not yet supported."); }
protected virtual Task <ISydneyResponse> DeleteAsync(ISydneyRequest request) => throw new NotImplementedException();
internal async Task <ISydneyResponse> HandleRequestAsync(ISydneyRequest request, ILogger logger, bool returnExceptionMessagesInResponse) { Stopwatch stopwatch = Stopwatch.StartNew(); try { ISydneyResponse response = null; switch (request.HttpMethod) { case HttpMethod.Get: response = await this.GetAsync(request); break; case HttpMethod.Post: response = await this.PostAsync(request); break; case HttpMethod.Delete: response = await this.DeleteAsync(request); break; case HttpMethod.Put: response = await this.PutAsync(request); break; case HttpMethod.Head: response = await this.HeadAsync(request); break; case HttpMethod.Patch: response = await this.PatchAsync(request); break; case HttpMethod.Options: response = await this.OptionsAsync(request); break; default: throw new NotImplementedException(); } logger.LogInformation($"Request completed after {stopwatch.Elapsed}, status code: {response.StatusCode}."); return(response); } catch (Exception exception) { HttpStatusCode statusCode = HttpStatusCode.InternalServerError; switch (exception) { case HttpResponseException hre: logger.LogWarning( hre, $"Request failed after {stopwatch.Elapsed}, status code: {hre.StatusCode}, exception: {hre}"); statusCode = hre.StatusCode; break; case NotImplementedException nie: logger.LogWarning( nie, $"Request made for unsupported HTTP method {request.HttpMethod}."); statusCode = HttpStatusCode.MethodNotAllowed; break; default: logger.LogError( exception, $"Unexpected exception processing request after {stopwatch.Elapsed}, exception: {exception}"); break; } return (new SydneyResponse( statusCode, returnExceptionMessagesInResponse ? exception.Message : null)); } }