Click to edit Master title style• Click to edit Master text styles – Second level • Third level ...
Agenda Who Am I? What is “lightweight” RestBucks REST Nancy
What is lightweight?3
What is lightweight?  Low ceremony  Low cruft  Conventions4
What is lightweight?  Open  Agile  Inexpensive5
Restbucks6
REST7
REST – Richardsons Maturity Model Level 3: Hypermedia Level 2: HTTP Verbs Level 1: Resources Level...
REST - Resources  The basic building blocks of web API  Anything with a URI  http://restbucks.com/menu/  h...
REST- Representations GET http://restbucks.com/order/19202048/ HTTP/1.1 Accept: application/vnd.restbucks+xml<?xml ver...
REST - Representations GET http://restbucks.com/order/19202048/ HTTP/1.1 Accept: application/vnd.restbucks+json{...
REST - verbs  GET  POST  PUT  DELETE  HEAD  OPTIONS  PATCH12
REST - Headers  Accept  Content-Type  If-None-Match  Etag13
14
Why Nancy?  “Close” to http  Very, very readable code  Very explicit routing  Embraces modularity ...
Nancy Basics Organizes your routes public class MainModule : NancyModule { public MainModule() { ...
Nancy Basics Defines which verbs you accepts public class MainModule : NancyModule { public MainModule() ...
Restbuck on Nancy – Place an Orderpublic OrdersResourceHandler(IRepository<Product> productRepository, ...
RestBucks on Nancy – View an Orderpublic OrderResourceHandler(IRepository<Order> orderRepository) : base(”/order”){ this....
RestBucks on Nancy – Cancel an Order Delete["/{orderId}/"] = parameters => Cancel((int) parameters.orderId); ...
RestBucks on Nancy –Pay an OrderPost["/{orderId}/payment"] = parameters => Pay((int) parameters.orderId, ...
RestBucks on Nancy – XML or JSONreturn Response.WithContent(Request.Headers.Accept, OrderRepresen...
RestBucks on Nancy – Conditional Gets return Response.WithContent(Request.Headers.Accept, ...
RestBucks on Nancy – Conditional Gets if (Request.IsNotModified(order)) return Response.NotModified(); ...
Nancy.Hosting Your Application Nancy Nancy.Hosting ...
Nancy.Hosting Usage:  > Install-Package Nancy.Hosting.* Hosts:  ASP.NET  WCF  Self  OWIN
Nancy.Testing [Test] public void WhenOrderHasNotChanged_ThenReturn304() { // Arrange var orderRepo = new Reposito...
Why Nancy?  “Close” to http  Very, very readable code  Very explicit routing  Embraces modularity ...
Why REST + Nancy  Lightweight  Low ceremony  Low cruft  Follows conventions  Open ...
More …  Restbucks on Nancy: http://github.com/horsdal/Restbucks-on-Nancy  Rest in Practice: http://restinpractic...
of 30

Nancy + rest mow2012

Published on: Mar 3, 2016
Published in: Technology      
Source: www.slideshare.net


Transcripts - Nancy + rest mow2012

  • 1. Click to edit Master title style• Click to edit Master text styles – Second level • Third level – Fourth level The Lightweight Approach to » Fifth level Building Web Based APIs with .NET MOW 201219-04-2012 1
  • 2. Agenda Who Am I? What is “lightweight” RestBucks REST Nancy
  • 3. What is lightweight?3
  • 4. What is lightweight?  Low ceremony  Low cruft  Conventions4
  • 5. What is lightweight?  Open  Agile  Inexpensive5
  • 6. Restbucks6
  • 7. REST7
  • 8. REST – Richardsons Maturity Model Level 3: Hypermedia Level 2: HTTP Verbs Level 1: Resources Level 0: POX-RPC8
  • 9. REST - Resources  The basic building blocks of web API  Anything with a URI  http://restbucks.com/menu/  http://restbucks.com/orders/  http://restbucks.com/order/42/  http://restbucks.com/order/42/payment/9
  • 10. REST- Representations GET http://restbucks.com/order/19202048/ HTTP/1.1 Accept: application/vnd.restbucks+xml<?xml version="1.0"?><order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="h <links> <link uri="http://restbucks.com/order/19202048" rel="http://restbucks <link uri="http://restbucks.com/order/19202048" rel="http://restbucks <link uri="http://restbucks.com/order/19202048" rel="http://restbucks <link uri="http://restbucks.com/order/19202048/payment" rel="http://r </links> <location>inShop</location> <cost>7.60000</cost> <items> <item> <name>Latte</name> <quantity>1</quantity> <milk>skim</milk> <size>large</size>10 </item>
  • 11. REST - Representations GET http://restbucks.com/order/19202048/ HTTP/1.1 Accept: application/vnd.restbucks+json{ "Location":inShop, "Cost":7.60000, "Items":[ { "Name":"Latte", "Quantity":1, "Preferences":{ "milk":"skim", "size":"large" } } ], "Status":1, "Links":[ {11 "Uri":"http://restbucks.com/order/19202048",
  • 12. REST - verbs  GET  POST  PUT  DELETE  HEAD  OPTIONS  PATCH12
  • 13. REST - Headers  Accept  Content-Type  If-None-Match  Etag13
  • 14. 14
  • 15. Why Nancy?  “Close” to http  Very, very readable code  Very explicit routing  Embraces modularity  Embraces IoC/DI  Embraces testing  Runs anywhere15
  • 16. Nancy Basics Organizes your routes public class MainModule : NancyModule { public MainModule() { Get["/"] = _ => "Hello from root"; } } public class SubModule : NancyModule { public SubModule() : base("subpath") { Get["/"] = _ => "Hello from subpath"; } }
  • 17. Nancy Basics Defines which verbs you accepts public class MainModule : NancyModule { public MainModule() { Get["/"] = _ => "Hello from root"; Post["/”] = _ => DoPost(Request.Form.my_value) Delete["/{id}”] = p => Delete(p.id); Put["/”] = _ => DoPut(Request.Body); Patch["/”] = _ => DoPatch(Request.Body); } } HEAD and OPTIONS and automatic
  • 18. Restbuck on Nancy – Place an Orderpublic OrdersResourceHandler(IRepository<Product> productRepository, IRepository<Order> orderRepository) : base("/orders"){ this.productRepository = productRepository; this.orderRepository = orderRepository; Post["/"] = _ => HandlePost(this.Bind<OrderRepresentation>());}private Response HandlePost(OrderRepresentation orderRepresentation){ var order = TryBuildOrder(orderRepresentation); if (!order.IsValid()) return InvalidOrderResponse(order); orderRepository.MakePersistent(order); return Created(order);}18
  • 19. RestBucks on Nancy – View an Orderpublic OrderResourceHandler(IRepository<Order> orderRepository) : base(”/order”){ this.orderRepository = orderRepository; Get["/{orderId}/”] = parameters => GetHandler((int) parameters.orderId); …}public Response GetHandler(int orderId){ var order = orderRepository.GetById(orderId); if (order == null) return HttpStatusCode.NotFound; if (order.Status == OrderStatus.Canceled) return Response.MovedTo(new ResourceLinker(CanceledOrderUri(orderId); if (Request.IsNotModified(order)) return Response.NotModified(); return Response.WithContent(Request.Headers.Accept, OrderRepresentationMapper.Map(order,Request.BaseUri())) .WithCacheHeaders(order);}19
  • 20. RestBucks on Nancy – Cancel an Order Delete["/{orderId}/"] = parameters => Cancel((int) parameters.orderId); public Response Cancel(int orderId) { var order = orderRepository.GetById(orderId); if (order == null) return HttpStatusCode.NotFound; order.Cancel("canceled from the rest interface"); return HttpStatusCode.NoContent; }20
  • 21. RestBucks on Nancy –Pay an OrderPost["/{orderId}/payment"] = parameters => Pay((int) parameters.orderId, this.Bind<PaymentRepresentation>());public Response Pay(int orderId, PaymentRepresentation paymentArgs){ var order = orderRepository.GetById(orderId); if (order == null) return HttpStatusCode.NotFound; order.Pay(paymentArgs.CardNumber, paymentArgs.CardOwner); return HttpStatusCode.OK; }21
  • 22. RestBucks on Nancy – XML or JSONreturn Response.WithContent(Request.Headers.Accept, OrderRepresentationMapper.Map(order, Request.BaseUri())) .WithCacheHeaders(order); public static Response WithContent<T>(this IResponseFormatter formatter, IEnumerable<Tuple<string, decimal>> acceptHeaders, T content) { var xmlWeight = CalculateWeightForContentType(acceptHeaders, "xml"); var jsonWeight = CalculateWeightForContentType(acceptHeaders, "json"); if (jsonWeight > xmlWeight) return formatter.AsJson(content); else return formatter.AsXml(content); }22
  • 23. RestBucks on Nancy – Conditional Gets return Response.WithContent(Request.Headers.Accept, OrderRepresentationMapper.Map(order, Request.BaseUri())) .WithCacheHeaders(order);public static Response WithCacheHeaders(this Response response, IVersionable versionable, TimeSpan? maxAge = null){ return response.WithHeaders( new { Header = "ETag", Value = string.Format(""{0}"", versionable.Version) }, new { Header = "Cache-Control", Value = string.Format("max-age={0}, public", maxAge ?? TimeSpan.FromSeconds(10)) }); }23
  • 24. RestBucks on Nancy – Conditional Gets if (Request.IsNotModified(order)) return Response.NotModified(); public static bool IsNotModified(this Request request, IVersionable versionable) { if (!request.Headers.IfNoneMatch.Any()) return false; var etag = request.Headers.IfNoneMatch.First(); return string.Format(""{0}"", versionable.Version) == etag; } public static Response NotModified(this IResponseFormatter formatter, TimeSpan? maxAge = null) { Response response = HttpStatusCode.NotModified; return response.WithHeaders( new { Header = "ReasonPhrase", Value = "Not modified"}, new { Header = "Cache-Control", Value = string.Format("max-age={0}, public", maxAge ?? TimeSpan.FromSeconds(10)) }); }24
  • 25. Nancy.Hosting Your Application Nancy Nancy.Hosting …
  • 26. Nancy.Hosting Usage:  > Install-Package Nancy.Hosting.* Hosts:  ASP.NET  WCF  Self  OWIN
  • 27. Nancy.Testing [Test] public void WhenOrderHasNotChanged_ThenReturn304() { // Arrange var orderRepo = new RepositoryStub<Order>(new Order(1, 123); var app = new Browser( new ConfigurableBootstrapper (with => { with.Dependency<IRepository<Product>>(…); with.Dependency<IRepository<Order>>(orderRepository); } )); // Act var response = app.Get("/order/123/", with => { with.HttpRequest(); with.Header("If-None-Match", ""1""); }); //Assert response.StatusCode.Should().Be.EqualTo(HttpStatusCode.NotModified);29}
  • 28. Why Nancy?  “Close” to http  Very, very readable code  Very explicit routing  Embraces modularity  Embraces IoC/DI  Embraces testing  Runs anywhere30
  • 29. Why REST + Nancy  Lightweight  Low ceremony  Low cruft  Follows conventions  Open  Agile31
  • 30. More …  Restbucks on Nancy: http://github.com/horsdal/Restbucks-on-Nancy  Rest in Practice: http://restinpractice.com/book.html  Nancy: www.nancyfx.org  Me:  Twitter: @chr_horsdal  Blog: horsdal.blogspot.com  email: chg@mjolner.dk32

Related Documents