{"id":13430450,"url":"https://github.com/christopherread/Obvs","last_synced_at":"2025-03-16T05:30:59.505Z","repository":{"id":28557693,"uuid":"32075146","full_name":"christopherread/Obvs","owner":"christopherread","description":"An observable microservice bus library for .NET, that wraps the underlying message transports in simple Rx based interfaces.","archived":false,"fork":false,"pushed_at":"2021-11-17T14:46:14.000Z","size":953,"stargazers_count":334,"open_issues_count":5,"forks_count":45,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-03-15T06:48:28.276Z","etag":null,"topics":["csharp","dotnet","messaging","microservices","observable","obvs","reactive-extensions","servicebus"],"latest_commit_sha":null,"homepage":"http://christopherread.github.io/Obvs","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christopherread.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-12T12:14:24.000Z","updated_at":"2025-03-07T17:20:57.000Z","dependencies_parsed_at":"2022-09-06T02:42:31.587Z","dependency_job_id":null,"html_url":"https://github.com/christopherread/Obvs","commit_stats":null,"previous_names":["inter8ection/obvs"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopherread%2FObvs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopherread%2FObvs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopherread%2FObvs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopherread%2FObvs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christopherread","download_url":"https://codeload.github.com/christopherread/Obvs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243695484,"owners_count":20332626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","messaging","microservices","observable","obvs","reactive-extensions","servicebus"],"created_at":"2024-07-31T02:00:53.852Z","updated_at":"2025-03-16T05:30:55.427Z","avatar_url":"https://github.com/christopherread.png","language":"C#","readme":"﻿\n# Obvs: an observable microservice bus\n## observable services, *obviously*\n\n[![Join the chat at https://gitter.im/inter8ection/Obvs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/inter8ection/Obvs?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n[![.NET](https://github.com/christopherread/Obvs/workflows/.NET/badge.svg)](https://github.com/christopherread/Obvs/actions)\n\n[![NuGet](https://img.shields.io/nuget/v/Obvs.svg)](https://www.nuget.org/packages/Obvs/)\n\n### Features\n\n* Obvs is just a library, not a framework - use as much or as little as you need.\n* Leverage messaging and Reactive Extensions to quickly compose a system of decoupled microservices.\n* Add new services and message contracts with a minimal amount of code and effort.\n* Don't tie yourself to any one transport, migrate between transports with minimal code changes required\n* Use a mix of transports and serialization formats, allowing you to pick what works for your services.\n* Declare a new Obvs ServiceBus easily using the fluent code based configuration.\n* Don't want to use Obvs message contract interfaces? Use the generic ServiceBus and supply your own.\n* Standardize on messaging semantics throughout by wrapping integrations with external API's as custom endpoints.\n* Don't distribute if you don't need to, Obvs ServiceBus includes a local in-memory bus.\n* Use one of the many available serialization extensions, or even write your own.\n* Easily debug and monitor your application using logging and performance counter extensions.\n\n### Versions/Roadmap\n\n* V6 - `System.Reactive 5.0`, supports `netstandard2.0`, `net472` and `net5.0`.  Mono-repo\n* V5 - `System.Reactive 4.1`, supports `netstandard2.0` and `net472`\n* V4 - `System.Reactive 3.1.1`, supports `netstandard1.6` and `net452` \n\n### More Details\n\n* Convention based messaging over topics/queues/streams per service.\n* Multiplexing of multiple message types over single topics/queues/streams.\n* Dynamic creation of deserializers per type, auto-discovery of message contracts.\n* Exceptions are caught and raised on an asynchronous error channel.\n\n### Extensions\n\n* Transports: ActiveMQ / RabbitMQ / NetMQ / AzureServiceBus / Kafka / EventStore\n* Serialization: XML / JSON.Net / NetJson / ProtoBuf / MsgPack\n* Logging: NLog / log4net\n* Monitoring: Performance Counters / ElasticSearch\n* Integrations: Slack\n\n## Example\n\nDefine a root message type to identify messages as belonging to your service:\n\n\tpublic interface IMyServiceMessage : IMessage { }\n\nCreate command/event/request/response message types:\n\n\tpublic class MyCommand : IMyServiceMessage, ICommand { }\n\n\tpublic class MyEvent : IMyServiceMessage, IEvent { }\n\n\tpublic class MyRequest: IMyServiceMessage, IRequest { }\n\t\n\tpublic class MyResponse : IMyServiceMessage, IResponse { }\n\nCreate your service bus:\n\n\tIServiceBus serviceBus = ServiceBus.Configure()\n        .WithActiveMQEndpoints\u003cIMyServiceMessage\u003e()\n            .Named(\"MyService\")\n            .UsingQueueFor\u003cICommand\u003e()\n            .ConnectToBroker(\"tcp://localhost:61616\")\n            .SerializedAsJson()\n            .AsClientAndServer()\n        .Create();\n\nSend commands:\n\n\tserviceBus.Commands.Subscribe(c =\u003e Console.WriteLine(\"Received a command!\"));\n\tawait serviceBus.SendAsync(new MyCommand());\n\nPublish events:\n\n\tserviceBus.Events.Subscribe(e =\u003e Console.WriteLine(\"Received an event!\"));\n\tawait serviceBus.PublishAsync(new MyEvent());\n\t\nRequest/response:\n\n\tserviceBus.Requests\n\t\t  .OfType\u003cMyRequest\u003e()\n\t\t  .Subscribe(request =\u003e serviceBus.ReplyAsync(request, new MyResponse()));\n\t\n\tserviceBus.GetResponses(new MyRequest())\n\t\t  .OfType\u003cMyResponse\u003e()\n\t\t  .Take(1)\n\t\t  .Timeout(TimeSpan.FromSeconds(1))\n\t\t  .Subscribe(r =\u003e Console.WriteLine(\"Received a response!\"), err =\u003e Console.WriteLine(\"Oh no!\"));\n\nDefine custom endpoints that can wrap API calls or integrations with other systems:\n\t\n\tpublic class MyCustomEndpoint : IServiceEndpointClient\n    \t{\n        \tType _serviceType = typeof(IMyCustomServiceMessage);\n\n        \tpublic IObservable\u003cIEvent\u003e Events\n        \t{\n            \t\tget\n            \t\t{\n                \t\t// subscribe to external MQ broker\n            \t\t}\n        \t}\n\n        \tpublic Task SendAsync(ICommand command)\n        \t{\n            \t\t// call external API\n        \t}\n\n        \tpublic IObservable\u003cIResponse\u003e GetResponses(IRequest request)\n        \t{\n            \t\t// call external API and wrap response in observable\n        \t}\n\n        \tpublic bool CanHandle(IMessage message)\n        \t{\n            \t\treturn _serviceType.IsInstanceOfType(message);\n        \t}\n    \t}\n\t\t\n\t...\n\n\tIServiceBus serviceBus = ServiceBus.Configure()\n          .WithActiveMQEndpoints\u003cIMyServiceMessage\u003e()\n            .Named(\"MyService\")\n            .UsingQueueFor\u003cICommand\u003e()\n            .ConnectToBroker(\"tcp://localhost:61616\")\n            .SerializedAsJson()\n            .AsClientAndServer()\n\t  .WithEndpoints(new MyCustomEndpoint())\n        .Create();\n\n## Run Examples in Docker\n\n\tcd examples\n\tdocker-compose up\n\n\tcd client\n\tdotnet run -f netcoreapp3.1 \n","funding_links":[],"categories":["Frameworks, Libraries and Tools","框架, 库和工具","Messaging Patterns","Distributed Computing","C# #"],"sub_categories":["Distributed Computing","分布式计算","Library"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopherread%2FObvs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristopherread%2FObvs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopherread%2FObvs/lists"}