• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
What is the ServiceStack?
 

What is the ServiceStack?

on

  • 484,907 views

What is it?

What is it?
Where did it come from?
What does it do?

Statistics

Views

Total Views
484,907
Views on SlideShare
10,929
Embed Views
473,978

Actions

Likes
17
Downloads
278
Comments
1

121 Embeds 473,978

http://www.servicestack.net 330073
https://servicestack.net 89718
http://servicestack.net 38562
http://www.scoop.it 8503
http://mono.servicestack.net 5304
https://twitter.com 388
http://localhost 266
http://api.servicestack.net 175
http://schemas.servicestack.net 113
http://translate.googleusercontent.com 87
http://techno-sphere.blogspot.com 79
http://aws.servicestack.net 73
http://jabbr.net 60
https://jabbr.net 51
https://schemas.servicestack.net 43
http://sparcgeeks.tumblr.com 39
http://ww2.servicestack.net 31
https://www.google.com 29
http://webcache.googleusercontent.com 27
http://abtasty.com 23
http://aprogrammingjourney.wordpress.com 22
http://ss-www.servicestack.net 19
http://ss-www.elasticbeanstalk.com 14
http://www.1system.com 12
https://razor-console.servicestack.net 11
http://techno-sphere.blogspot.in 10
http://techno-sphere.blogspot.ca 10
http://prlog.ru 10
http://techno-sphere.blogspot.ru 10
http://servicestack.net. 9
https://www.google.ie 8
http://www.razor-console.servicestack.net 8
https://www.google.de 7
https://store.servicestack.net 6
http://news.google.com 6
http://techno-sphere.blogspot.de 6
http://ormlite.servicestack.net 6
http://razr.servicestack.net 5
http://plus.url.google.com 5
http://ww.servicestack.net 5
http://cc.bingj.com 5
http://www.services.servicestack.net 5
https://www.google.co.uk 4
http://rockstars.servicestack.net 4
https://translate.googleusercontent.com 4
http://blog.servicestack.net 4
http://docs.servicestack.net 4
http://10.1.10.3 4
http://techno-sphere.blogspot.co.uk 3
http://131.253.14.98 3
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • do you make a power point file? thankyou!
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

What is the ServiceStack? What is the ServiceStack? Presentation Transcript

  • What is the ServiceStack
  • What is the ServiceStackhttp://www.servicestack.net https://github.com/ServiceStack Core Team Demis Bellot @demisbellot Steffen Müller @arxisos Sergey Bogdanov @desunit https://github.com/ServiceStack/ServiceStack/wiki/Contributors
  • What is the ServiceStack • What is it? • Where did it come from? • What does it do?
  • More than Services Simple - Fast - Lightweight - Testable - Clean ServiceStack.Text ServiceStack.Redis .NET’s fastest JSON, JSV, CSV Text Serializers .NET’s leading Redis Client ServiceStack.OrmLite ServiceStack.Caching Fast, typed, Code-First Micro ORM Clean Caching Provider InterfacesSQL Server, Sqlite, PostgreSQL, MySQL, Oracle, Firebird In-Memory, Redis, Memcached, Azure, Disk More: node.js-powered Bundler, Logging, Auto-Mappers, Service Clients, Markdown Razor, Configuration Providers, Enhanced Funq IOC
  • More than Services Simple - Fast - Lightweight - Testable - Clean ServiceStack.Text ServiceStack.Redis .NET’s fastest JSON, JSV, CSV Text Serializers .NET’s leading Redis Client Code-First POCOs ServiceStack.OrmLite ServiceStack.Caching Fast, typed, Code-First Micro ORM Clean Caching Provider Interfaces Re-use same POCOs in allSQL Server, Sqlite, PostgreSQL, MySQL, Oracle, Firebird ServiceStack libs In-Memory, Redis, Memcached, Azure, Disk More: node.js-powered Bundler, Logging, Auto-Mappers, Service Clients, Markdown Razor, Configuration Providers, Enhanced Funq IOC, ...
  • Simple Demo Poco Powerhttps://github.com/ServiceStack/ServiceStack.UseCases/tree/master/PocoPower
  • Implementation var appSettings = new AppSettings(); var config = appSettings.Get<Config>("my.config", new Config { GitHubName = "mythz", TwitterName = "ServiceStack" });Object graphs in Config deserialize into clean POCOs:<appSettings name=”my.config” value=”{GitHubName:mythz,TwitterName:ServiceStack}”/> var github = new GithubGateway(); var repos = github.GetAllUserAndOrgsReposFor(config.GitHubName);Avoid Web.Config completely with sensible default values var twitter = new TwitterGateway(); var tweets = twitter.GetTimeline(config.TwitterName); External providers to return clean POCOs "Loaded {0} repos and {1} tweets...".Print(repos.Count, tweets.Count); OrmLiteConfig.DialectProvider = SqliteDialect.Provider; //using (IDbConnection db = "~/db.sqlite".MapAbsolutePath().OpenDbConnection()) Use Extension methods to: using (IDbConnection db = ":memory:".OpenDbConnection()) { db.DropAndCreateTable<Tweet>(); • DRY logic db.DropAndCreateTable<GithubRepo>(); • Create readable code • Avoid abstractions / restrictions "nInserting {0} Tweets into Sqlite:".Print(tweets.Count); db.InsertAll(tweets); • Allow extensibility "nLatest {0} Tweets from Sqlite:".Print(Show); db.Select<Tweet>(q => q.OrderByDescending(x => x.Id).Limit(Show)).PrintDump(); "nInserting {0} Repos into Sqlite:".Print(repos.Count); Code-First POCOs db.InsertAll(repos); "nLatest {0} Repos from Sqlite:".Print(Show); • Master authority of your models db.Select<GithubRepo>(q => q.OrderByDescending(x => x.Id).Limit(Show)).PrintDump(); • Start from C# project out } • Schema’s inferred from POCO’s using (var redis = new RedisClient()) • Reduce industrial knowledge { • Use Conventions where possible "nInserting {0} Tweets into Redis:".Print(tweets.Count); redis.StoreAll(tweets); • Typed API "n{0} Tweets from Redis:".Print(Show); • Intelli-sense & productivity redis.GetAll<Tweet>().Take(Show).PrintDump(); • Refactoring "nInserting {0} Repos into Redis:".Print(repos.Count); • Correctness redis.StoreAll(repos); "n{0} Repos from Redis:".Print(Show); redis.GetAll<GithubRepo>().Take(Show).PrintDump(); }
  • Benchmarks https://github.com/mythz/ScalingDotNETBrad Abrams (Google employee, former Microsoft PM and co-author of .NET Framework Design Guidelines)
  • OrmLite Benchmarks
  • JSON Benchmarks
  • Redis vs RavenDB Benchmarks
  • @ServiceStack favorites: Popular 114 Contributors Since July 2011https://github.com/ServiceStack/ServiceStack/wiki/Contributors http://www.servicestack.net/100k-downloads/
  • Where it began?Enterprise .NET 2007
  • Where it began?Followed the .NET Enterprise Play Book• Leveraged external Enterprise consultants• Adopted Microsofts prescribed Enterprise SOA solution at the time: CSF, WCF and BizTalk• We had an Enterprise / Technical Architect round-table• Split Internal systems into different independent SOA services (we really wanted to do SOA :)• Enterprise architects defined web service contracts using UML and XSDs: • XSD Messages were implementation ignorant • Explicitly validated XSD conformance at runtime • Leveraged SOAP/XML/XSD: Headers, Inheritance, Namespaces • UML -> XSDs -> DTOs -> used in WCF Service Contracts -> WSDLs -> Service Reference Proxies• CSFs state-full session was used as a Bus orchestrating communication between services• Services were discoverable, participating in CSFs Session• Service endpoints were WCF Services, leveraged SOAP headers for extra WS-* compliance• Wrote code Designed perfectly normalized databases
  • What happened? Disaster Code-gen DTOs were:• Brittle: A simple namespace change would break existing messages• Infectious: Domain logic binded to code-gen DTOs and version changes led to multiple parallel implementations• Friction-encumbered: Services needed to be built/ deployed in lock-step with each other We pioneered:• Xml everywhere: We had XML config to manage our XML- configured services and resources• Week-long downtimes: between breaking major upgrades, required to flush old messages out of the system• Glacial Development: The turn-around time to get a field from UML/XSD/dll to C# was measured in days• Enterprise Hacks: Added "ViewBags" to most messages to allow us to stuff arbitrary data in existing messages without changing the schema
  • What happened?• SOAP • Frail, Slow, Poor programmatic fit, Only accessible to SOAP Clients, Incompatible impls• RPC method signatures • Brittle, promotes lots of chatty client-specific API, Typed-API mandates code-gen, blurred service layer• Code-Gen • Changes breaks code, inhibits DRY, forces abstraction, multiple versions results in parallel implementations• Bus / State-full Sessions • Less accessible, harder to debug and test, easier to fail
  • What we did right?• SOA Design: Coarse-grained, well-defined, self-describing, time-decoupled, re-usable messages• Pub/Sub: Promotes the most loosely coupled architecture i.e. Sender decoupled from Receiver• Message Queues: Replay-able async idempotent messages provide the most reliable and durable inter-service communications• Martin Fowler & Co knew what the best-practices for remote services were: • Remote Facade: Using message-based, coarse-grained/batch-full interfaces minimizing round-trips, promoting creation of fewer but tolerant and version-able service interfaces • DTOs: Avoid any effort expended dealing with wire-format in application code • Gateway: Removes comms logic in app code and provides a swappable comms layer with a good isolation and testing abstraction
  • What is a Service?
  • What is a Service?What it’s notIts NOT to force the use of a particular technology or platformIts NOT to conform to a pre-defined specification or constraintsIts NOT to use a pre-determined format or follow a pre-scribed architecture
  • What is a Service? Its to provide a service
  • What is a Service?Its to provide a serviceto encapsulate some re-usable capabilities and make them available remotely
  • What is a Service?Its to provide a serviceto encapsulate some re-usable capabilities and make them available remotely ★ To as many clients as possible ★ In the most accessible and interoperable way ★ With the least amount of effort ★ With maximum amount of re-useGood characteristics ★ Version-able, tolerant and resilient to changes ★ End-to-end productivity Legend: ★ Goals that ServiceStack is optimized for :)
  • What is a Service?Its to provide a serviceto encapsulate some re-usable capabilities and make them available remotely ★ To as many clients as possible Services offer the highest level of software ★ In the most accessible and interoperable way re-use. Being able to easily take advantage ★ With the least amount of effort of these capabilities is where benefits of ★ With maximum amount of re-use SOA are ultimately derived. To maximize the benefits, ServiceStack isGood characteristics optimized in reducing the burden in creating and consuming services, end-to-end. ★ Version-able, tolerant and resilient to changes ★ End-to-end productivity Legend: ★ Goals that ServiceStack is optimized for :)
  • mflowLess 1/2 development team Magnitude more resultsBest-Practices SOA PlatformFaster, more scalable services ServiceStack was born
  • Visualizing ServiceStackBuilt on raw ASP.NET IHttpHandler’s Stand-alone HttpListener, MQ, RCON hosts Runs Everywhere Clean Slate using Code-First POCO’s New Auth, Caching, Session Providers
  • Visualizing ServiceStack
  • Visualizing ServiceStack
  • Advantages of Message-based Services• Theyre easy to version and evolve as youre freely able to add/remove functionality without error• Theyre easy to route, chain, hijack and decorate through to different handlers and pipelines• Theyre easy to serialize and proxy through to remote services• Theyre easy to log, record, defer and replay• Theyre easy to map and translate to and from domain models• Ideal for concurrency as immutable messages are thread-safe and are easily multiplexed• Theyre easy to extend with generic solutions and enhance with re-usable functionality https://github.com/ServiceStack/ServiceStack/wiki/Advantages-of-message-based-web-services
  • Message-based remote services are everywhereConcurrency in F# – Part III – Erlang Style Message Passing type Message = Word of string | Fetch of IChannel<Map<string,int>> | Stoptype WordCountingAgent() =    let counter = MailboxProcessor.Start(fun inbox ->             let rec loop(words : Map<string,int>) =                async { let! msg = inbox.Receive()                        match msg with                        | Word word ->                            if words.ContainsKey word then                                let count = words.[word]                                let words = words.Remove word                                return! loop(words.Add (word, (count + 1)) )                            else                                return! loop(words.Add (word, 1) )                        | Stop ->                            return ()                        | Fetch replyChannel ->                            do replyChannel.Post(words) //post to reply channel and continue                            return! loop(words) }              loop(Map.empty)) //The initial state     member a.AddWord(n) = counter.Post(Word(n))    member a.Stop() = counter.Post(Stop)    member a.Fetch() = counter.PostSync(fun replyChannel -> Fetch(replyChannel)) http://strangelights.com/blog/archive/2007/10/24/1601.aspx
  • Message-based remote services are everywhereGoogle Protocol Buffer Messages http://code.google.com/p/protobuf/message Person {  required int32 id = 1;  required string name = 2;  optional string email = 3;}Amazon C# SDK Petboard: An ASP.NET Sample Using Amazon S3 and Amazon SimpleDBSelectRequest selectRequest = new SelectRequest()    .WithSelectExpression("select * from `petboard-public`");SelectResponse selectResponse = _simpleDBClient.Select(selectRequest); http://aws.amazon.com/articles/3592
  • Message-based remote services are everywhere Scala Actors Actors in Go type ReadReq struct { import scala.actors.Actor._   key string import java.net.{InetAddress, UnknownHostException}   ack chan<- string } case class LookupIP(name: String, respondTo: Actor) type WriteReq struct { case class LookupResult(   key, val string   name: String, }   address: Option[InetAddress] ) c := make(chan interface{}) object NameResolver extends Actor { go func() {   def act() {   m := make(map[string]string)     loop {   for {       react {     switch r := (<-c).(type) {         case LookupIP(name, actor) =>     case ReadReq:           actor ! LookupResult(name, getIp(name))       r.ack <- m[r.key]       }     case WriteReq:     }       m[r.key] = r.val   }     } }   } }()http://www.cs.helsinki.fi/u/wikla/OTS/Sisalto/examples/html/ch30.html https://docs.google.com/present/view?id=df36r82q_5gdq5gzth
  • non-message-based service examples
  • non-message-based service examples namespace HelloWebAPI.Controllers Your First ASP.NET Web API (C#) Tutorial: {     public class ProductsController : ApiController     {         Product[] products = new Product[]         {             new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },             new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },             new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }         };         public IEnumerable<Product> GetAllProducts()         {             return products;         }         public Product GetProductById(int id)         {             var product = products.FirstOrDefault((p) => p.Id == id);             if (product == null)             {                 throw new HttpResponseException(HttpStatusCode.NotFound);             }             return product;         }         public IEnumerable<Product> GetProductsByCategory(string category)         {             return products.Where(                 (p) => string.Equals(p.Category, category,                     StringComparison.OrdinalIgnoreCase));         }     } }http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
  • Your First ASP.NET Web API (C#) Tutorial: The Same Services in ServiceStack: public class ProductsControllerV2 : ApiController public class FindProducts : IReturn<List<Product>>    {     {        public IEnumerable<Product> GetAllProducts() 5 vs 2         public string Category { get; set; }        {            return products; Services &         public decimal? PriceGreaterThan { get; set; }     }        } Entry Points     public class GetProduct : IReturn<Product>        public Product GetProductById(int id)     {        {         public int? Id { get; set; }            var product = products.FirstOrDefault((p) => p.Id == id);         public string Name { get; set; }            if (product == null)     }            {                throw new HttpResponseException(HttpStatusCode.NotFound);     public class ProductsService : IService            }     {            return product;         public object Get(FindProducts request)        }         {             var ret = products.AsQueryable();        public Product GetProductByName(string categoryName)             if (request.Category != null)        {                 ret = ret.Where(x => x.Category == request.Category);            var product = products.FirstOrDefault((p) => p.Name == categoryName);             if (request.PriceGreaterThan.HasValue)            if (product == null)                 ret = ret.Where(x => x.Price > request.PriceGreaterThan.Value);            {             return ret;                throw new HttpResponseException(HttpStatusCode.NotFound);         }            }            return product;         public object Get(GetProduct request)        }         {             var product = request.Id.HasValue        //Adding existing services with more RPC method calls                 ? products.FirstOrDefault(x => x.Id == request.Id.Value)        public IEnumerable<Product> GetProductsByCategory(string category)                 : products.FirstOrDefault(x => x.Name == request.Name);        {            return products.Where(             if (product == null)                (p) => string.Equals(p.Category, category,                 throw new HttpError(HttpStatusCode.NotFound, "Product does not exist");                    StringComparison.OrdinalIgnoreCase));        }             return product;         }        public IEnumerable<Product> GetProductsByPriceGreaterThan(decimal price)     }        {            return products.Where((p) => p.Price > price);        } SOA Design: Services differentiated by calling semantics and Return type:    } e.g. Find* filters results, whilst Get* fetches unique records:
  • Familiar?WCF-Style Services vs ServiceStack Web Services public class Customers {public interface IService int[] Ids;{ string[] UserNames; Customer GetCustomerById(int id); string[] Emails; Customer[] GetCustomerByIds(int[] id); } Customer GetCustomerByUserName(string userName); Customer[] GetCustomerByUserNames(string[] userNames); public class CustomersResponse { Customer GetCustomerByEmail(string email); Customer[] Results; Customer[] GetCustomerByEmails(string[] emails); }}Any combination of the above can be fulfilled by 1 remote call, by the same single web service - i.e what ServiceStack encouragesFewer and more batch-full services require less maintenance and promote the development of more re-usable and efficient services. In addition, message APIs are much moreresilient to changes as youre able to safely add more functionality or return more data without breaking or needing to re-gen existing clients. Message-based APIs also lend thembetter for cached, asynchronous, deferred, proxied and reliable execution with the use of brokers and proxies.
  • Calling the Product Services in ServiceStack     private const string BaseUri = "http://localhost:1337";   /* All Products:     IRestClient client = new JsonServiceClient(BaseUri); [ {     "nAll Products:".Print(); Id: 1,     client.Get(new FindProducts()).PrintDump(); Name: Tomato Soup, Category: Groceries, Price: 1 }, { Id: 2, Name: Yo-yo, Category: Toys, // Notes: Price: 3.75 // - No Code-Gen: Same generic service client used for all operations }, // - When Custom Routes are specified it uses those, otherwise falls back to pre-defined routes { // - IRestClient interface implemented by JSON, JSV, Xml, MessagePack, ProtoBuf Service Clients Id: 3, // - Service returns IEnumerable[Product] but JSON, JSV serializers happily handles List[Product] fine Name: Hammer, Category: Hardware, Price: 16.99 } ] */     /* Toy Products:     List<Product> toyProducts = client.Get(new FindProducts { Category = "Toys" }); [     "nToy Products:".Print(); {     toyProducts.PrintDump(); Id: 2, Name: Yo-yo, Category: Toys, Price: 3.75 } ] */
  • Calling the Product Services in ServiceStack    List<Product> productsOver2Bucks = client.Get(new FindProducts { PriceGreaterThan = 2 });     /* Products over $2:    "nProducts over $2:".Print(); [    productsOver2Bucks.PrintDump(); { Id: 2, Name: Yo-yo, Category: Toys, Price: 3.75 }, { Id: 3, Name: Hammer, Category: Hardware, Price: 16.99 } ] */    var hardwareOver2Bucks = client.Get(new FindProducts {PriceGreaterThan=2, Category="Hardware"});     /* Hardware over $2:    "nHardware over $2:".Print(); [    hardwareOver2Bucks.PrintDump(); { Id: 3, Name: Hammer, Category: Hardware, Price: 16.99 } ] */    Product product1 = client.Get(new GetProduct { Id = 1 });    /* Product with Id = 1:    "nProduct with Id = 1:".Print(); {    product1.PrintDump(); Id: 1, Name: Tomato Soup, Category: Groceries, Price: 1 } */
  • Testable All Clients share same IRestClient & IServiceClient interfaces for New API Tests easy mocking and integration tests protected static IRestClient[] RestClients = [Test, TestCaseSource("RestClients")] { public void Can_GET_AllReqstars(IRestClient client) new JsonServiceClient(BaseUri), { new XmlServiceClient(BaseUri), var allReqstars = client.Get<List<Reqstar>>("/reqstars"); new JsvServiceClient(BaseUri), Assert.That(allReqstars.Count, Is.EqualTo(ReqstarsService.SeedData.Length)); new MsgPackServiceClient(BaseUri), } } ; [Test, TestCaseSource("ServiceClients")] protected static IServiceClient[] ServiceClients = public void Can_SEND_AllReqstars_PrettyTypedApi(IServiceClient client) RestClients.OfType<IServiceClient>().ToArray(); { var allReqstars = client.Send(new AllReqstars()); Assert.That(allReqstars.Count, Is.EqualTo(ReqstarsService.SeedData.Length)); } https://github.com/ServiceStack/ServiceStack/blob/master/tests/RazorRockstars.Console.Files/ReqStarsService.cs Same Unit Test can be re-used in JSON, XML, JSV, SOAP 1.1/1.2 Integration Tests https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Tests/WebServicesTests.cs
  • Frictionless Easy to serialize form into a model and send to Ser vice Gateway and bind results to Response Productive end-to-end typed pipeline
  • ServiceStack Demo Hello, World! http://tinyurl.com/hellomonkeyspace
  • Hello World Implementation[Route("/hellohtml/{Name}")] public class HelloService : Service {public class HelloHtml public object Get(HelloHtml request) {{ return "<h1>Hello, {0}!</h1>".Fmt(request.Name); Override Content-Type public string Name { get; set; } }} [AddHeader(ContentType = "text/plain")] return raw strings, bytes, public object Get(HelloText request) { Streams, etc.[Route("/hellotext/{Name}")] return "<h1>Hello, {0}!</h1>".Fmt(request.Name);public class HelloText }{ [AddHeader(ContentType = "image/png")] public string Name { get; set; } public object Get(HelloImage request) {} var width = request.Width.GetValueOrDefault(640); var height = request.Height.GetValueOrDefault(360);[Route("/helloimage/{Name}")] var bgColor = request.Background != null ? Color.FromName(request.Background) : Color.ForestGreen;public class HelloImage var fgColor = request.Foreground != null ? Color.FromName(request.Foreground) : Color.White;{ var image = new Bitmap(width, height); public string Name { get; set; } using (var g = Graphics.FromImage(image)) { g.Clear(bgColor); public int? Width { get; set; } var drawString = "Hello, {0}!".Fmt(request.Name); public int? Height { get; set; } var drawFont = new Font("Times", request.FontSize.GetValueOrDefault(40)); public int? FontSize { get; set; } var drawBrush = new SolidBrush(fgColor); public string Foreground { get; set; } var drawRect = new RectangleF(0, 0, width, height); public string Background { get; set; } var drawFormat = new StringFormat {} LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center }; [Route("/hello/{Name}")] g.DrawString(drawString, drawFont, drawBrush, drawRect, drawFormat);public class Hello : IReturn<HelloResponse> var ms = new MemoryStream();{ image.Save(ms, ImageFormat.Png); Get Content-Negotiation public string Name { get; set; } return ms; and typed C# clients when} } } returning DTOspublic class HelloResponse public object Get(Hello request) {{ return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) }; public string Result { get; set; } }} } C# Client calls with: var response = client.Get(new Hello { Name = "ServiceStack" });
  • ServiceStack Demo SMessagehttps://github.com/ServiceStack/ServiceStack.UseCases/tree/master/Reusability
  • SMessage Implementation public partial class SMessageService : Service public partial class SMessageService : Service { { public EmailProvider Email { get; set; } public object Any(FindReceipts request) public FacebookGateway Facebook { get; set; } { public TwitterGateway Twitter { get; set; } var skip = request.Skip.GetValueOrDefault(0); public IMessageFactory MsgFactory { get; set; } var take = request.Take.GetValueOrDefault(20); return Db.Select<SMessageReceipt>(q => q.Limit(skip, take)); public object Any(SMessage request) } { var sw = Stopwatch.StartNew(); public object Any(EmailMessage request) { if (!request.Defer) var sw = Stopwatch.StartNew(); { Db.InsertAll(Email.Process(request)); var results = new List<SMessageReceipt>(); return new SMessageResponse { TimeTakenMs = sw.ElapsedMilliseconds }; results.AddRange(Email.Send(request)); } results.AddRange(Facebook.Send(request)); results.AddRange(Twitter.Send(request)); Easily defer execution public object Any(CallFacebook request) Db.InsertAll(results); by dropping DTOs in { } registered MQs var sw = Stopwatch.StartNew(); else Db.InsertAll(Facebook.Process(request)); { return new SMessageResponse { TimeTakenMs = sw.ElapsedMilliseconds }; using (var producer = MsgFactory.CreateMessageProducer()) } { Email.CreateMessages(request).ForEach(producer.Publish); public object Any(PostStatusTwitter request) Facebook.CreateMessages(request).ForEach(producer.Publish); { Twitter.CreateMessages(request).ForEach(producer.Publish); var sw = Stopwatch.StartNew(); } Db.InsertAll(Twitter.Process(request)); } return new SMessageResponse { TimeTakenMs = sw.ElapsedMilliseconds }; } return new SMessageResponse { } Deferred messages TimeTakenMs = sw.ElapsedMilliseconds, are picked up by MQ }; } broker that calls back into } existing services
  • Why Mono?
  • Why Mono? Scale at $0 licensing cost Bring .NET to exciting Platforms
  • Why Mono? Scale at $0 licensing cost • Redis • PostgreSQL, MySQL, SQLite, Firebird Lets build the next Instagram!
  • Why Mono? Scale at $0 licensing cost Where to host servicestack.net?
  • Why Mono? Scale at $0 licensing cost 2.67 GHz 1.67 GHz 2GB RAM Where to host 1.75GB RAM servicestack.net? 80GB HDD 100GB HDD 4TB traffic 2TB traffic
  • Why Mono? Scale at $0 licensing cost 2.67 GHz 1.67 GHz 2GB RAM Where to host 1.75GB RAM servicestack.net? 80GB HDD 100GB HDD 4TB traffic 2TB traffic €19.90 mo > 11x Cheaper! €219.50 mo €238.8 year €2,634 year
  • Why Mono? Bring .NET to exciting Platforms
  • Features:
  • Sergey Bogdanov @desunitFeatures: Swagger Integration
  • Sergey Bogdanov @desunitFeatures: Swagger Integration
  • https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorizationFeatures: Authentication Providers var appSettings = new AppSettings(); Plugins.Add(new AuthFeature( () => new CustomUserSession(), //Use your own typed Custom UserSession type new IAuthProvider[] { new CredentialsAuthProvider(), //HTML Form post of UserName/Password credentials new TwitterAuthProvider(appSettings), //Sign-in with Twitter new FacebookAuthProvider(appSettings), //Sign-in with Facebook new DigestAuthProvider(appSettings), //Sign-in with Digest Auth new BasicAuthProvider(), //Sign-in with Basic Auth new GoogleOpenIdOAuthProvider(appSettings), //Sign-in with Google OpenId new YahooOpenIdOAuthProvider(appSettings), //Sign-in with Yahoo OpenId new OpenIdOAuthProvider(appSettings), //Sign-in with Custom OpenId })); https://github.com/ServiceStack/SocialBootstrapApi/
  • https://github.com/ServiceStack/ServiceStack/wiki/ValidationFeatures: Validation End-to-end typed API for exceptions try { var client = new JsonServiceClient(BaseUri); var response = client.Send<UserResponse>(new User()); } catch (WebServiceException webEx) { /* webEx.StatusCode = 400 webEx.ErrorCode = ArgumentNullException webEx.Message = Value cannot be null. Parameter name: Name webEx.StackTrace = (your Server Exception StackTrace - if DebugMode is enabled) webEx.ResponseDto = (your populated Response DTO) webEx.ResponseStatus = (your populated Response Status DTO) webEx.GetFieldErrors() = (individual errors for each field if any) */ } https://github.com/ServiceStack/ServiceStack/wiki/Validation
  • https://github.com/ServiceStack/ServiceStack/wiki/CachingFeatures: Caching Providers container.Register<ICacheClient>(new MemoryCacheClient()); public class OrdersService : Service { public object Get(CachedOrders request) { var cacheKey = "unique_key_for_this_request"; return base.RequestContext.ToOptimizedResultUsingCache(base.Cache, cacheKey, () => { //Delegate is executed if item doesnt exist in cache //Any response DTO returned here will be cached automatically } ); } } Redis, Memcached, Disk and Azure Caching Providers also available Sessions works with any Cache Provider http://www.servicestack.net/ServiceStack.Northwind/
  • https://github.com/ServiceStack/ServiceStack/wiki/Request-loggerFeatures: Request Logger Query String Filters
  • https://github.com/ServiceStack/ServiceStack/wiki/Built-in-profilingFeatures: Mini Profiler Built-in protected void Application_BeginRequest(object src, EventArgs e) { if (Request.IsLocal) Profiler.Start(); } protected void Application_EndRequest(object src, EventArgs e) { Profiler.Stop(); }
  • @ServiceStack Thank Youhttp://www.servicestack.net https://github.com/ServiceStack Core Team Demis Bellot @demisbellot Steffen Müller @arxisos Sergey Bogdanov @desunit https://github.com/ServiceStack/ServiceStack/wiki/Contributors