{"id":23623646,"url":"https://github.com/firesharkstudios/butterfly-web","last_synced_at":"2025-08-30T23:32:35.021Z","repository":{"id":91266216,"uuid":"215400602","full_name":"firesharkstudios/butterfly-web","owner":"firesharkstudios","description":"Simple RESTlike and Subscription API server in C#","archived":false,"fork":false,"pushed_at":"2020-04-21T23:24:01.000Z","size":5961,"stargazers_count":13,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-11T10:39:57.812Z","etag":null,"topics":["csharp","embedio","real-time","redhttp","rest","subscription"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/firesharkstudios.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-15T21:32:29.000Z","updated_at":"2023-11-24T02:57:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"0221aed4-a9b0-465a-bb3e-aaae58450e21","html_url":"https://github.com/firesharkstudios/butterfly-web","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firesharkstudios%2Fbutterfly-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firesharkstudios%2Fbutterfly-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firesharkstudios%2Fbutterfly-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/firesharkstudios%2Fbutterfly-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/firesharkstudios","download_url":"https://codeload.github.com/firesharkstudios/butterfly-web/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231539702,"owners_count":18392334,"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","embedio","real-time","redhttp","rest","subscription"],"created_at":"2024-12-27T20:50:12.878Z","updated_at":"2024-12-27T20:50:14.688Z","avatar_url":"https://github.com/firesharkstudios.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Butterfly.Web ![Butterfly Logo](https://raw.githubusercontent.com/firesharkstudios/Butterfly/master/img/logo-40x40.png) \n\n\u003e Simple RESTlike and Subscription API server in C#\n\n## Getting Started\n\n### Install from Nuget\n\n| Name | Package | Install |\n| --- | --- | --- |\n| Butterfly.Web | [![nuget](https://img.shields.io/nuget/v/Butterfly.Web.svg)](https://www.nuget.org/packages/Butterfly.Web/) | `nuget install Butterfly.Web` |\n| Butterfly.Web.EmbedIO | [![nuget](https://img.shields.io/nuget/v/Butterfly.Web.EmbedIO.svg)](https://www.nuget.org/packages/Butterfly.Web.EmbedIO/) | `nuget install Butterfly.Web.EmbedIO` |\n| Butterfly.Web.RedHttpServer | [![nuget](https://img.shields.io/nuget/v/Butterfly.Web.RedHttpServer.svg)](https://www.nuget.org/packages/Butterfly.Web.RedHttpServer/) | `nuget install Butterfly.Web.RedHttpServer` |\n\n### Install from Source Code\n\n```git clone https://github.com/firesharkstudios/butterfly-web```\n\n## Overview\n\n*Butterfly.Web* defines an *IWebApi* interface to define RESTlike APIs and defines an *ISubscriptionApi* to stream real-time updates to clients.\n\n*Butterfly.Web.EmbedIO* implements the *Butterfly.Web* interfaces using the lightweight [EmbedIO](https://github.com/unosquare/embedio) web server.\n\n*Butterfly.Web.RedHttpServer* implements the *Butterfly.Web* interfaces using the Kestral based [RedHttpServer](https://github.com/RedHttp/Red).\n \n## Using IWebApi\n\nAn *IWebApi* instance allows defining a RESTlike API like this...\n\n```cs\n// Create an IWebApi instance using EmbedIO or RedHttpServer\n\nwebApi.OnPost(\"/api/todo/insert\", async (req, res) =\u003e {\n    var todo = await req.ParseAsJsonAsync\u003cDict\u003e();\n    // Do something to insert the todo\n});\n\nwebApi.OnPost(\"/api/todo/delete\", async (req, res) =\u003e {\n    var id = await req.ParseAsJsonAsync\u003cstring\u003e();\n    // Do something to delete the todo\n});\n\n// Don't forget to compile\nwebApi.Compile();\n```\n\n### Request Handling\n\nThere are many ways to receive data from a client...\n\n```cs\n// Using path params\nwebApi.OnGet(\"/api/todo/{id}\", (req, res) =\u003e {\n    // Opening /api/todo/123 would print id=123 below\n    Console.WriteLine($\"id={req.PathParams[\"id\"]}\");\n});\n\n// Using query params\nwebApi.OnGet(\"/api/todo\", (req, res) =\u003e {\n    // Opening /api/todo?id=123 would print id=123 below\n    Console.WriteLine($\"id={req.QueryParams[\"id\"]}\");\n});\n\n// Using post body that is JSON encoded\nwebApi.OnPost(\"/api/todo\", async(req, res) =\u003e {\n    // A javascript client posting JSON data with...\n    //     $.ajax('/api/todo', {\n    //         method: 'POST',\n    //         data: JSON.stringify({ id: \"123\" }),\n    //     });\n    // would echod id=123 below\n    var data = await req.ParseAsJsonAsync\u003cDictionary\u003cstring, string\u003e\u003e();\n    Console.WriteLine($\"id={data[\"id\"]}\");\n});\n\n// Using post body that is URL encoded\nwebApi.OnPost(\"/api/todo\", async(req, res) =\u003e {\n    // A javascript client posting JSON data with...\n    //     var formData = new FormData();\n    //     formData.append(\"id\", \"123\");\n    //     $.ajax('/api/todo', {\n    //         method: 'POST',\n    //         data: formData,\n    //     });\n    // would echod id=123 below\n    var data = await req.ParseAsUrlEncodedAsync();\n    Console.WriteLine($\"id={data[\"id\"]}\");\n});\n```\n\n### Response Handling\n\nThere are many ways to send a response to a client...\n\n```cs\n// Respond with plain text\nwebApi.OnPost(\"/api/todo\", async(req, res) =\u003e {\n    await res.WriteAsTextAsync(\"OK\");\n});\n\n// Respond with JSON\nwebApi.OnPost(\"/api/todo\", async(req, res) =\u003e {\n    await res.WriteAsJsonAsync(new {\n        result = \"OK\"\n    });\n});\n\n// Redirect the client\nwebApi.OnGet(\"/api/todo/{id}\", (req, res) =\u003e {\n    res.SendRedirect(\"/api/todo/not-found\");\n});\n```\n\n## Using ISubscriptionApi\n\nAn *ISubscriptionApi* instance allows clients to receive real-time updates like this...\n\n```cs\n// Create an ISubscriptionApi instance using EmbedIO or RedHttpServer\n\nsubscriptionApi.OnSubscribe(\"echoes\", async(vars, channel) =\u003e {\n    int count = 0;\n    return Butterfly.Util.RunEvery(() =\u003e {\n        channel.Queue(\"Echo\", $\"Echo #{++count}\");\n    }, 2000);\n});\n```\n\nA client subscribing to the *echoes* subscription above would receive messages every two seconds (first message would have type *Echo* and text *Echo #1*).\n\nThe subscription handler must return an *IDisposable* instance that is disposed when the client unsubscribes or disconnects.\n\n## Using EmbedIO\n\n[EmbedIO](https://github.com/unosquare/embedio) is a capable low footprint web server that can be used to implement both the *IWebApi* and *ISubscriptionApi* interfaces. \n\nThe *EmbedIOContext* class is a convenience class that creates *IWebApi* and *ISubscriptionApi* instances using an [EmbedIO](https://github.com/unosquare/embedio) web server.\n\nIn the *Package Manager Console*...\n\n```\nInstall-Package Butterfly.Web.EmbedIO\n```\n\nIn your application...\n\n```csharp\nvar context = new Butterfly.Web.EmbedIO.EmbedIOContext(\"http://+:8000/\");\n\n// Declare your Web API and Subscription API like...\ncontext.WebApi.OnPost(\"/api/todo/insert\", async (req, res) =\u003e {\n   // Do something\n});\ncontext.WebApi.OnPost(\"/api/todo/delete\", async (req, res) =\u003e {\n   // Do something\n});\ncontext.SubscriptionApi.OnSubscribe(\"todos\", (vars, channel) =\u003e {\n   // Do something\n});\n\ncontext.Start();\n```\n\n## Using RedHttpServer\n\n[RedHttpServer](https://github.com/rosenbjerg/Red) is a Kestrel/ASP.NET Core based web server that can be used to implement both the *IWebApi* and *ISubscriptionApi* interfaces. \n\nThe *RedHttpServerContext* class is a convenience class that creates *IWebApi* and *ISubscriptionApi* instances using [RedHttpServer](https://github.com/rosenbjerg/Red).\n\nIn the *Package Manager Console*...\n\n```\nInstall-Package Butterfly.RedHttpServer\n```\n\nIn your application...\n\n```csharp\nvar context = new Butterfly.Web.RedHttpServer.RedHttpServerContext(\"http://+:8000/\");\n\n// Declare your Web API and Subscription API like...\ncontext.WebApi.OnPost(\"/api/todo/insert\", async (req, res) =\u003e {\n   // Do something\n});\ncontext.WebApi.OnPost(\"/api/todo/delete\", async (req, res) =\u003e {\n   // Do something\n});\ncontext.SubscriptionApi.OnSubscribe(\"todos\", (vars, channel) =\u003e {\n   // Do something\n});\n\ncontext.Start();\n```\n\n## Contributing\n\nIf you'd like to contribute, please fork the repository and use a feature\nbranch. Pull requests are warmly welcome.\n\n## Licensing\n\nThe code is licensed under the [Mozilla Public License 2.0](http://mozilla.org/MPL/2.0/).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiresharkstudios%2Fbutterfly-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffiresharkstudios%2Fbutterfly-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiresharkstudios%2Fbutterfly-web/lists"}