SlideShare a Scribd company logo
1 of 59
What is the ServiceStack
What is the ServiceStack
http://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 Interfaces
SQL 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 all
SQL 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 Power


https://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/ScalingDotNET




Brad 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 2011
https://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 Microsoft's 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 -> XSD's -> DTOs -> used in WCF Service Contracts -> WSDLs -> Service Reference Proxies
•   CSF's state-full session was used as a Bus orchestrating communication between services
•   Services were discoverable, participating in CSF's Session
•   Service endpoints were WCF Services, leveraged SOAP headers for extra WS-* compliance
•   Wrote code Designed perfectly normalized databases
What happened? Disaster

            Code-gen DTO's 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 not
It's NOT to force the use of a particular technology or platform
It's NOT to conform to a pre-defined specification or constraints
It's NOT to use a pre-determined format or follow a pre-scribed architecture
What is a Service?




                     It's to provide a service
What is a Service?


It's to provide a service
to encapsulate some re-usable capabilities and make them available remotely
What is a Service?


It's to provide a service
to 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-use


Good characteristics
   ★ Version-able, tolerant and resilient to changes
   ★ End-to-end productivity

                                                                          Legend:
                                                                              ★   Goals that ServiceStack is optimized for :)
What is a Service?


It's to provide a service
to 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 is
Good 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 :)
mflow

Less 1/2 development team
  Magnitude more results

Best-Practices SOA Platform
Faster, more scalable services




   ServiceStack was born
Visualizing ServiceStack

Built 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



• They're easy to version and evolve as you're freely able to add/remove functionality without error
• They're easy to route, chain, hijack and decorate through to different handlers and pipelines
• They're easy to serialize and proxy through to remote services
• They're easy to log, record, defer and replay
• They're easy to map and translate to and from domain models
• Ideal for concurrency as immutable messages are thread-safe and are easily multiplexed

• They're 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 everywhere
Concurrency in F# – Part III – Erlang Style Message Passing
   type Message = Word of string | Fetch of IChannel<Map<string,int>> | Stop

type 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 everywhere
Google 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 SimpleDB
SelectRequest 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 encourages
Fewer 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 more
resilient to changes as you're able to safely add more functionality or return more data without breaking or needing to re-gen existing clients. Message-based APIs also lend them
better 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 DTOs
public 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


                            SMessage


https://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
                                        @desunit



Features: Swagger Integration
Sergey Bogdanov
                                        @desunit



Features: Swagger Integration
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization




Features: 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/Validation




Features: 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/Caching




Features: 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 doesn't 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-logger




Features: Request Logger




                       Query String Filters
https://github.com/ServiceStack/ServiceStack/wiki/Built-in-profiling




Features: 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 You
http://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

More Related Content

What's hot

Service oriented web development with OSGi
Service oriented web development with OSGiService oriented web development with OSGi
Service oriented web development with OSGiCarsten Ziegeler
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Knoldus Inc.
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?Demis Bellot
 
VCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyVCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyFastly
 
Fighting Against Chaotically Separated Values with Embulk
Fighting Against Chaotically Separated Values with EmbulkFighting Against Chaotically Separated Values with Embulk
Fighting Against Chaotically Separated Values with EmbulkSadayuki Furuhashi
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습John Kim
 
Monitoring OSGi Applications with the Web Console - Carsten Ziegeler
Monitoring OSGi Applications with the Web Console - Carsten ZiegelerMonitoring OSGi Applications with the Web Console - Carsten Ziegeler
Monitoring OSGi Applications with the Web Console - Carsten Ziegelermfrancis
 
Ice mini guide
Ice mini guideIce mini guide
Ice mini guideAdy Liu
 
Vert.x – The problem of real-time data binding
Vert.x – The problem of real-time data bindingVert.x – The problem of real-time data binding
Vert.x – The problem of real-time data bindingAlex Derkach
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014Yubei Li
 
G rpc lection1
G rpc lection1G rpc lection1
G rpc lection1eleksdev
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestackDemis Bellot
 
Fluentd at Bay Area Kubernetes Meetup
Fluentd at Bay Area Kubernetes MeetupFluentd at Bay Area Kubernetes Meetup
Fluentd at Bay Area Kubernetes MeetupSadayuki Furuhashi
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPAFaren faren
 
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...Codemotion
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play frameworkFelipe
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebeanFaren faren
 
NginX - good practices, tips and advanced techniques
NginX - good practices, tips and advanced techniquesNginX - good practices, tips and advanced techniques
NginX - good practices, tips and advanced techniquesClaudio Borges
 

What's hot (20)

Service oriented web development with OSGi
Service oriented web development with OSGiService oriented web development with OSGi
Service oriented web development with OSGi
 
Bosh 2.0
Bosh 2.0Bosh 2.0
Bosh 2.0
 
Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2Introduction to Apache Kafka- Part 2
Introduction to Apache Kafka- Part 2
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?
 
VCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to FastlyVCL template abstraction model and automated deployments to Fastly
VCL template abstraction model and automated deployments to Fastly
 
Fighting Against Chaotically Separated Values with Embulk
Fighting Against Chaotically Separated Values with EmbulkFighting Against Chaotically Separated Values with Embulk
Fighting Against Chaotically Separated Values with Embulk
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습vert.x 소개 및 개발 실습
vert.x 소개 및 개발 실습
 
Monitoring OSGi Applications with the Web Console - Carsten Ziegeler
Monitoring OSGi Applications with the Web Console - Carsten ZiegelerMonitoring OSGi Applications with the Web Console - Carsten Ziegeler
Monitoring OSGi Applications with the Web Console - Carsten Ziegeler
 
Ice mini guide
Ice mini guideIce mini guide
Ice mini guide
 
Vert.x – The problem of real-time data binding
Vert.x – The problem of real-time data bindingVert.x – The problem of real-time data binding
Vert.x – The problem of real-time data binding
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014
 
G rpc lection1
G rpc lection1G rpc lection1
G rpc lection1
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestack
 
Fluentd at Bay Area Kubernetes Meetup
Fluentd at Bay Area Kubernetes MeetupFluentd at Bay Area Kubernetes Meetup
Fluentd at Bay Area Kubernetes Meetup
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPA
 
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...
Meetup RomaJS - introduzione interattiva a Node.js - Luca Lanziani - Codemoti...
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebean
 
NginX - good practices, tips and advanced techniques
NginX - good practices, tips and advanced techniquesNginX - good practices, tips and advanced techniques
NginX - good practices, tips and advanced techniques
 

Similar to What is the ServiceStack?

What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?Demis Bellot
 
jclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Colejclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian ColeEverett Toews
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 
Connect + Docker + AWS = Bitbucket Pipelines
Connect + Docker + AWS = Bitbucket PipelinesConnect + Docker + AWS = Bitbucket Pipelines
Connect + Docker + AWS = Bitbucket PipelinesAtlassian
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusEmily Jiang
 
Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudMassimiliano Dessì
 
Come costruire una Platform As A Service con Docker, Kubernetes Go e Java
Come costruire una Platform As A Service con Docker, Kubernetes Go e JavaCome costruire una Platform As A Service con Docker, Kubernetes Go e Java
Come costruire una Platform As A Service con Docker, Kubernetes Go e JavaCodemotion
 
Microservices with containers in the cloud
Microservices with containers in the cloudMicroservices with containers in the cloud
Microservices with containers in the cloudEugene Fedorenko
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationBen Hall
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...DataStax Academy
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disquszeeg
 
Logisland "Event Mining at scale"
Logisland "Event Mining at scale"Logisland "Event Mining at scale"
Logisland "Event Mining at scale"Thomas Bailet
 
Clustrix Database Percona Ruby on Rails benchmark
Clustrix Database Percona Ruby on Rails benchmarkClustrix Database Percona Ruby on Rails benchmark
Clustrix Database Percona Ruby on Rails benchmarkClustrix
 
(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++Amazon Web Services
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...Julia Cherniak
 
Containerd Project Update: FOSDEM 2018
Containerd Project Update: FOSDEM 2018Containerd Project Update: FOSDEM 2018
Containerd Project Update: FOSDEM 2018Phil Estes
 
Kubernetes for java developers - Tutorial at Oracle Code One 2018
Kubernetes for java developers - Tutorial at Oracle Code One 2018Kubernetes for java developers - Tutorial at Oracle Code One 2018
Kubernetes for java developers - Tutorial at Oracle Code One 2018Anthony Dahanne
 
Immutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaImmutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaAOE
 
Cloud-native .NET Microservices mit Kubernetes
Cloud-native .NET Microservices mit KubernetesCloud-native .NET Microservices mit Kubernetes
Cloud-native .NET Microservices mit KubernetesQAware GmbH
 

Similar to What is the ServiceStack? (20)

What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?
 
jclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Colejclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Cole
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Connect + Docker + AWS = Bitbucket Pipelines
Connect + Docker + AWS = Bitbucket PipelinesConnect + Docker + AWS = Bitbucket Pipelines
Connect + Docker + AWS = Bitbucket Pipelines
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
 
Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloud
 
Come costruire una Platform As A Service con Docker, Kubernetes Go e Java
Come costruire una Platform As A Service con Docker, Kubernetes Go e JavaCome costruire una Platform As A Service con Docker, Kubernetes Go e Java
Come costruire una Platform As A Service con Docker, Kubernetes Go e Java
 
Microservices with containers in the cloud
Microservices with containers in the cloudMicroservices with containers in the cloud
Microservices with containers in the cloud
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS Application
 
Liferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for DevelopersLiferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for Developers
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
Logisland "Event Mining at scale"
Logisland "Event Mining at scale"Logisland "Event Mining at scale"
Logisland "Event Mining at scale"
 
Clustrix Database Percona Ruby on Rails benchmark
Clustrix Database Percona Ruby on Rails benchmarkClustrix Database Percona Ruby on Rails benchmark
Clustrix Database Percona Ruby on Rails benchmark
 
(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
 
Containerd Project Update: FOSDEM 2018
Containerd Project Update: FOSDEM 2018Containerd Project Update: FOSDEM 2018
Containerd Project Update: FOSDEM 2018
 
Kubernetes for java developers - Tutorial at Oracle Code One 2018
Kubernetes for java developers - Tutorial at Oracle Code One 2018Kubernetes for java developers - Tutorial at Oracle Code One 2018
Kubernetes for java developers - Tutorial at Oracle Code One 2018
 
Immutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS LambdaImmutable Deployments with AWS CloudFormation and AWS Lambda
Immutable Deployments with AWS CloudFormation and AWS Lambda
 
Cloud-native .NET Microservices mit Kubernetes
Cloud-native .NET Microservices mit KubernetesCloud-native .NET Microservices mit Kubernetes
Cloud-native .NET Microservices mit Kubernetes
 

Recently uploaded

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 

Recently uploaded (20)

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 

What is the ServiceStack?

  • 1. What is the ServiceStack
  • 2. What is the ServiceStack http://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
  • 3. What is the ServiceStack • What is it? • Where did it come from? • What does it do?
  • 4. 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 Interfaces SQL 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
  • 5. 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 all SQL 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, ...
  • 6. Simple Demo Poco Power https://github.com/ServiceStack/ServiceStack.UseCases/tree/master/PocoPower
  • 7. 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(); }
  • 8. Benchmarks https://github.com/mythz/ScalingDotNET Brad Abrams (Google employee, former Microsoft PM and co-author of .NET Framework Design Guidelines)
  • 11. Redis vs RavenDB Benchmarks
  • 12. @ServiceStack favorites: Popular 114 Contributors Since July 2011 https://github.com/ServiceStack/ServiceStack/wiki/Contributors http://www.servicestack.net/100k-downloads/
  • 14. Where it began? Followed the .NET Enterprise Play Book • Leveraged external Enterprise consultants • Adopted Microsoft's 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 -> XSD's -> DTOs -> used in WCF Service Contracts -> WSDLs -> Service Reference Proxies • CSF's state-full session was used as a Bus orchestrating communication between services • Services were discoverable, participating in CSF's Session • Service endpoints were WCF Services, leveraged SOAP headers for extra WS-* compliance • Wrote code Designed perfectly normalized databases
  • 15. What happened? Disaster Code-gen DTO's 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
  • 16. 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
  • 17. 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
  • 18. What is a Service?
  • 19. What is a Service? What it’s not It's NOT to force the use of a particular technology or platform It's NOT to conform to a pre-defined specification or constraints It's NOT to use a pre-determined format or follow a pre-scribed architecture
  • 20. What is a Service? It's to provide a service
  • 21. What is a Service? It's to provide a service to encapsulate some re-usable capabilities and make them available remotely
  • 22. What is a Service? It's to provide a service to 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-use Good characteristics ★ Version-able, tolerant and resilient to changes ★ End-to-end productivity Legend: ★ Goals that ServiceStack is optimized for :)
  • 23. What is a Service? It's to provide a service to 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 is Good 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 :)
  • 24. mflow Less 1/2 development team Magnitude more results Best-Practices SOA Platform Faster, more scalable services ServiceStack was born
  • 25. Visualizing ServiceStack Built 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
  • 28. Advantages of Message-based Services • They're easy to version and evolve as you're freely able to add/remove functionality without error • They're easy to route, chain, hijack and decorate through to different handlers and pipelines • They're easy to serialize and proxy through to remote services • They're easy to log, record, defer and replay • They're easy to map and translate to and from domain models • Ideal for concurrency as immutable messages are thread-safe and are easily multiplexed • They're easy to extend with generic solutions and enhance with re-usable functionality https://github.com/ServiceStack/ServiceStack/wiki/Advantages-of-message-based-web-services
  • 29. Message-based remote services are everywhere Concurrency in F# – Part III – Erlang Style Message Passing type Message = Word of string | Fetch of IChannel<Map<string,int>> | Stop type 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
  • 30. Message-based remote services are everywhere Google 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 SimpleDB SelectRequest selectRequest = new SelectRequest()     .WithSelectExpression("select * from `petboard-public`"); SelectResponse selectResponse = _simpleDBClient.Select(selectRequest); http://aws.amazon.com/articles/3592
  • 31. 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
  • 33. 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
  • 34. 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:
  • 35. 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 encourages Fewer 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 more resilient to changes as you're able to safely add more functionality or return more data without breaking or needing to re-gen existing clients. Message-based APIs also lend them better for cached, asynchronous, deferred, proxied and reliable execution with the use of brokers and proxies.
  • 36. 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 } ] */
  • 37. 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 } */
  • 38. 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
  • 39. 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
  • 40. ServiceStack Demo Hello, World! http://tinyurl.com/hellomonkeyspace
  • 41. 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 DTOs public 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" });
  • 42. ServiceStack Demo SMessage https://github.com/ServiceStack/ServiceStack.UseCases/tree/master/Reusability
  • 43. 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
  • 45. Why Mono? Scale at $0 licensing cost Bring .NET to exciting Platforms
  • 46. Why Mono? Scale at $0 licensing cost • Redis • PostgreSQL, MySQL, SQLite, Firebird Lets build the next Instagram!
  • 47. Why Mono? Scale at $0 licensing cost Where to host servicestack.net?
  • 48. 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
  • 49. 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
  • 50. Why Mono? Bring .NET to exciting Platforms
  • 52. Sergey Bogdanov @desunit Features: Swagger Integration
  • 53. Sergey Bogdanov @desunit Features: Swagger Integration
  • 54. https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization Features: 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/
  • 55. https://github.com/ServiceStack/ServiceStack/wiki/Validation Features: 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
  • 56. https://github.com/ServiceStack/ServiceStack/wiki/Caching Features: 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 doesn't 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/
  • 58. https://github.com/ServiceStack/ServiceStack/wiki/Built-in-profiling Features: 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(); }
  • 59. @ServiceStack Thank You http://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

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n