{"id":17239321,"url":"https://github.com/rehacktive/monoservice","last_synced_at":"2025-03-26T02:36:51.472Z","repository":{"id":149775020,"uuid":"522227926","full_name":"rehacktive/monoservice","owner":"rehacktive","description":null,"archived":false,"fork":false,"pushed_at":"2022-08-12T16:18:20.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-30T23:44:16.961Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rehacktive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2022-08-07T13:58:22.000Z","updated_at":"2022-08-11T15:23:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"e95c11e2-7c15-4b4e-9163-091484136bd5","html_url":"https://github.com/rehacktive/monoservice","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/rehacktive%2Fmonoservice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehacktive%2Fmonoservice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehacktive%2Fmonoservice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rehacktive%2Fmonoservice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rehacktive","download_url":"https://codeload.github.com/rehacktive/monoservice/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245577653,"owners_count":20638353,"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":[],"created_at":"2024-10-15T05:48:22.928Z","updated_at":"2025-03-26T02:36:51.448Z","avatar_url":"https://github.com/rehacktive.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"### MONOSERVICE - modular microservice using Golang plugins\n\nThe idea is to have a very simple service that uses Golang plugins compiled as modules (.so) to implement different HTTP handlers.\nEach module can be worked on at different times, compiled and deployed, the service will detect a new module and load/use it.\n\nEXPERIMENTAL - WORK IN PROGRESS - TEST MISSING\n\n#### Step 1\n\nEach plugin needs to implement the following interface, defined in service.go:\n\n```go\ntype HandlerInterface interface {\n\tInit()                                                 // this method will initialize the module\n\tPath() string                                          // the path handled\n\tProcess(r *monoservice.HTTPRequest) utils.JSONResponse \t\t   // the logic for the handler\n\tMethods() []string                                     // HTTP methods used\n}\n```\n\nso for example:\n\n```go\ntype handlerPlugin struct{}\nvar HandlerPlugin handlerPlugin\n\nfunc (p handlerPlugin) Init() {\n\tlog.Println(\"hello plugin initialized\")\n}\n\nfunc (p handlerPlugin) Path() string {\n\treturn \"/hello\"\n}\n\nfunc (p handlerPlugin) Process(r *monoservice.HTTPRequest) monoservice.JSONResponse {\n\treturn monoservice.JSONResponse{\n\t\tJSONContent: `{\"message\":\"hello from the plugin\"}`,\n\t\tCode:        http.StatusOK,\n\t}\n}\n\nfunc (p handlerPlugin) Methods() []string {\n\treturn []string{http.MethodGet}\n}\n```\n\nnote that the HandlerPlugin is expected, so do not change this part, only the methods implementation.\nInit() could be used to do specific task at start (connect to a database, for example). The rest is self explainatory.\n\n#### Step 2\n\nBuild the plugin:\n\n```sh\ngo build -buildmode=plugin -o ./modules/helloplugin.so ./plugins/hello/hello_plugin.go\n```\n\nThis will generate an ```helloplugin.so``` file inside the modules folder, that is an ELF shared object.\n\n### Step 3\n\nUse the module with the service. For example running it with:\n\n```sh\ngo run service.go -MODULE_FOLDER=modules/\n```\n\n(that's by default the modules folder name)\n\nThis will scan for modules inside the folder and add/expose them, like defined in the plugin code.\n\nA simple test will reveal that all is working:\n\n```sh\ncurl http://localhost:8880/hello \n\nhello from the plugin\n```\n\n### Hot reload and important details\n\nThe service supports hot reload of modules, this means that you can implement a specific handler, then modify the behaviour and \ncopy the new .so file in the folder and everything will work **automagically**.\n\nCaveat: the module code **needs** to be different and so the module compiled file name, otherwise nothing will be reloaded\n(and it could panic) - this is due to the plugin.Open(...) method that doesn't work on the same file and behaves sometimes weirdly.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehacktive%2Fmonoservice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frehacktive%2Fmonoservice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frehacktive%2Fmonoservice/lists"}