{"id":37059653,"url":"https://github.com/jirenius/csharp-res","last_synced_at":"2026-01-14T06:44:17.177Z","repository":{"id":40915720,"uuid":"160516191","full_name":"jirenius/csharp-res","owner":"jirenius","description":"RES protocol service library for .NET","archived":false,"fork":false,"pushed_at":"2023-05-24T07:07:10.000Z","size":491,"stargazers_count":13,"open_issues_count":3,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-26T05:43:53.891Z","etag":null,"topics":["csharp","microservice","nats-server","netstandard","netstandard20","real-time","realtime","resgate","rest-api"],"latest_commit_sha":null,"homepage":"","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/jirenius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-05T12:39:02.000Z","updated_at":"2023-06-13T08:27:20.000Z","dependencies_parsed_at":"2023-01-24T14:30:15.512Z","dependency_job_id":null,"html_url":"https://github.com/jirenius/csharp-res","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/jirenius/csharp-res","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirenius%2Fcsharp-res","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirenius%2Fcsharp-res/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirenius%2Fcsharp-res/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirenius%2Fcsharp-res/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jirenius","download_url":"https://codeload.github.com/jirenius/csharp-res/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirenius%2Fcsharp-res/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","microservice","nats-server","netstandard","netstandard20","real-time","realtime","resgate","rest-api"],"created_at":"2026-01-14T06:44:16.555Z","updated_at":"2026-01-14T06:44:17.164Z","avatar_url":"https://github.com/jirenius.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"https://resgate.io\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg width=\"100\" src=\"https://resgate.io/img/resgate-logo.png\" alt=\"Resgate logo\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n\n\u003ch2 align=\"center\"\u003e\u003cb\u003eRES Service for .NET\u003c/b\u003e\u003cbr/\u003eSynchronize Your Clients\u003c/h2\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"http://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.nuget.org/packages/ResgateIO.Service\"\u003e\u003cimg src=\"https://img.shields.io/nuget/v/ResgateIO.Service.svg\" alt=\"NuGet\"\u003e\u003c/a\u003e\n\u003ca href=\"https://travis-ci.com/jirenius/csharp-res\"\u003e\u003cimg src=\"https://travis-ci.com/jirenius/csharp-res.svg?branch=master\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\nLibrary for .NET used to create next generation REST, real time, and RPC APIs, where all your reactive web clients are synchronized seamlessly through [Resgate](https://github.com/resgateio/resgate).\n\nVisit [Resgate.io](https://resgate.io) for more information.\n\n## As easy as\n```csharp\nResService service = new ResService(\"example\");\nservice.AddHandler(\"model\", new DynamicHandler()\n    .Get(r =\u003e r.Model(new {\n        message = \"Hello, World!\"\n    }))\n    .Access(r =\u003e r.AccessGranted()));\nservice.Serve(\"nats://127.0.0.1:4222\");\n```\n\n## Examples\n\n| Example | Description\n| --- | ---\n| [Hello World](examples/01_HelloWorld/) | Smallest of services serving a static message.\n| [Edit Text](examples/02_EditText/) | Single text field that is updated in real time.\n| [Book Collection](examples/03_BookCollection/) | List of book titles \u0026 authors that can be edited by many.\n| [Search](examples/04_Search/) | Make live queries against a large customer database.\n\n## Basic usage\n\n#### Create a new service\n\n```csharp\nResService service = new ResService(\"myservice\");\n```\n\n#### Define a handler class for a model resource\n\n```csharp\n[ResourcePattern(\"mymodel\")]\nclass MyModelHandler : BaseHandler\n{\n    private readonly object model = new\n    {\n        message = \"Hello, .NET World!\"\n    };\n\n    public void Get(IModelRequest request)\n    {\n        request.Model(model);\n    }\n}\n```\n\n#### Define a handler class for a collection resource\n\n```csharp\n[ResourcePattern(\"mycollection\")]\nclass MyCollectionHandler : BaseHandler\n{\n    private readonly object[] collection = new object[]{\n        \"first\", \"second\", \"third\"\n    };\n\n    public void Get(ICollectionRequest request)\n    {\n        request.Collection(collection);\n    }\n}\n```\n\n#### Define methods on a handler class\n\n```csharp\n[ResourcePattern(\"math\")]\nclass MyResourceHandler : BaseHandler\n{\n    [CallMethod(\"double\")]\n    public void Double(ICallRequest r)\n    {\n        r.Ok(2 * (double)r.Params[\"value\"]);\n    }\n}\n```\n\n#### Add/register handler for a resource\n```csharp\nservice.AddHandler(new MyResourceHandler());\n```\n\n#### Add handlers for parameterized resources\n\n```csharp\nservice.AddHandler(\"article.$id\", new DynamicHandler()\n    .Access(r =\u003e r.AccessGranted())\n    .ModelGet(r =\u003e\n    {\n        if (DB.TryGetArticle(r.PathParams[\"id\"], out Article article))\n            r.Model(article);\n        else\n            r.NotFound();\n    }));\n```\n\n#### Send change event on model update\nA change event will update the model on all subscribing clients.\n\n```csharp\nMyModel mymodel = new MyModel { Name = \"foo\" };\nMyModel mymodel = new MyModel { Name = \"foo\" };\nservice.With(\"example.mymodel\", resource =\u003e\n{\n    mymodel.Name = \"bar\";\n    resource.ChangeEvent(new Dictionary\u003cstring, object\u003e {\n        { \"name\", \"bar\" }\n    });\n});\n```\n\n#### Send add event on collection update:\nAn add event will update the collection for all subscribing clients.\n\n```csharp\nvar mycollection = new List\u003cstring\u003e { \"first\", \"second\" };\nservice.With(\"example.mycollection\", resource =\u003e\n{\n    resource.AddEvent(\"third\", mycollection.Count);\n    mycollection.Add(\"third\");\n});\n```\n\n#### Add handlers for authentication\n\n```csharp\nservice.AddHandler(\"myauth\", new DynamicHandler()\n    .AuthMethod(\"login\", r =\u003e\n    {\n        if ((string)r.Params[\"password\"] == \"mysecret\")\n        {\n            r.TokenEvent(new { user = \"admin\" });\n            r.Ok();\n        }\n        else\n        {\n            r.InvalidParams(\"Wrong password\");\n        }\n    }));\n```\n\n#### Add handlers for access control (with wildcard \"\u003e\")\n\n```csharp\nservice.AddHandler(\"\u003e\", new DynamicHandler()\n    .Access(r =\u003e\n    {\n        if (r.Token != null \u0026\u0026 (string)r.Token[\"user\"] == \"admin\")\n            r.AccessGranted();\n        else\n            r.AccessDenied();\n    }));\n```\n\n#### Add async handler\n```csharp\nservice.AddHandler(\"store.users\", new DynamicHandler()\n    .Get(async r =\u003e\n    {\n        var users = await DB.QueryAsync(\"SELECT id FROM users\");\n        r.Collection(users.Select(u =\u003e new Ref(\"store.user.\" + u.Id)));\n    }));\n```\n\n#### Start service\n\n```csharp\nservice.Serve(\"nats://127.0.0.1:4222\");\n```\n\n## Credits\n\nInspiration and support in development from [github.com/novagen](https://github.com/novagen), who wrote an initial .NET library for Resgate.\n\n## Contributing\n\nThe .NET library is still under development, but the API is mostly settled. Any feedback on the library API or its implementation is highly appreciated!\n\nOnce the API is fully settled, the package will be moved to the [resgateio](https://github.com/resgateio/) GitHub organization.\n\nIf you find any issues, feel free to [report them](https://github.com/jirenius/csharp-res/issues/new) as an Issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjirenius%2Fcsharp-res","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjirenius%2Fcsharp-res","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjirenius%2Fcsharp-res/lists"}