{"id":16989070,"url":"https://github.com/blackmann/resteasy","last_synced_at":"2026-04-22T16:37:09.765Z","repository":{"id":59045531,"uuid":"528691791","full_name":"blackmann/resteasy","owner":"blackmann","description":null,"archived":false,"fork":false,"pushed_at":"2022-08-30T19:50:35.000Z","size":23,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-28T14:44:26.737Z","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/blackmann.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}},"created_at":"2022-08-25T04:21:17.000Z","updated_at":"2023-12-04T19:07:41.000Z","dependencies_parsed_at":"2022-09-11T06:51:09.810Z","dependency_job_id":null,"html_url":"https://github.com/blackmann/resteasy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/blackmann/resteasy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackmann%2Fresteasy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackmann%2Fresteasy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackmann%2Fresteasy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackmann%2Fresteasy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blackmann","download_url":"https://codeload.github.com/blackmann/resteasy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackmann%2Fresteasy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32145870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T15:33:03.595Z","status":"ssl_error","status_checked_at":"2026-04-22T15:30:42.712Z","response_time":58,"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":[],"created_at":"2024-10-14T03:05:22.263Z","updated_at":"2026-04-22T16:37:04.758Z","avatar_url":"https://github.com/blackmann.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# resteasy\n\nThis framework is based on [gin](https://github.com/gin-gonic/gin) and inspired\nby [FeathersJS](https://github.com/feathersjs/feathers). That is, this library/framework allows you to develop REST\nservices with a rapid workflow. The API is easy to follow/learn.\n\n## Examples\n\n```go\npackage demo\n\nimport (\n\trest \"github.com/blackmann/resteasy\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc main() {\n\trouter := gin.Default()\n\tgroup := router.Group(\"/demo\")\n\n\tfindHandler := func(p rest.Params) (interface{}, *rest.ServiceError) {\n\t\treturn []int{1, 2, 3}, nil\n\t}\n\n\tgetHandler := func(id string, p rest.Params) (interface{}, *rest.ServiceError) {\n\t\treturn map[string]string{\"title\": \"Hello world\"}, nil\n\t}\n\n\tservice, allowedMethods := rest.NewService().\n\t\tFind(findHandler). // Resolves on /demo\n\t\tGet(getHandler). // Resolves /demo/123\n\t\tService()\n\n\trest.With(service, allowedMethods...).Register(group)\n\n\t_ = router.Run()\n}\n\n```\n\nThat was a quick and simple demonstration on how to use `resteasy`. Look inside the [examples/](/examples) folder for\nmore.\n\n## Concepts\n\n### Methods\n\nFollowing similar convention from FeathersJS, methods are nicknamed as the following:\n\n| Nickname | Method/Path        |                                             |\n|----------|--------------------|:--------------------------------------------|\n| find     | `GET` /demo        | The index path, where you return all items. |\n| get      | `GET` /demo/:id    | Get a single item                           |\n| create   | `POST` /demo/      |                                             |\n| patch    | `PATCH` /demo/:id  | Patch a single item                         |\n| update   | `PUT` /demo/:id    | Replace a single item                       |\n| remove   | `DELETE` /demo/:id |                                             |\n\nThese may feel foreign at first sight, but they make it easy for you to implement services that are not directly coupled\nto HTTP request methods. This also allows to test your service implementations in isolation from HTTP request\nprocessing.\n\n### Hooks\n\nHooks help perform some actions before or after a request is handled by the _service_. For example, you may want to\nauthenticate, check authorization, [populate params](#params) or perform some side effects. You can add as many hooks\nfor `.After()` or `.Before()` as you needed. The hook is passed the gin request context.\n\nIf you don't want to continue with the request, (eg. user not authorized), you can call `ctx.Abort()`. It's not\nrecommended, however, to call `ctx.Next()` in a hook as it may mess up the hooks flow.\n\n```go\npackage demo\n\nimport (\n\trest \"github.com/blackmann/resteasy\"\n\t\"github.com/gin-gonic/gin\"\n\t\"net/http\"\n)\n\nfunc main() {\n\trouter := gin.Default()\n\n\tgetHandler := func(id string, p rest.Params) (interface{}, *rest.ServiceError) {\n\t\treturn map[string]string{}, nil\n\t}\n\n\tcheckAuthorization := func(ctx *gin.Context) {\n\t\tif ctx.Param(\"id\") == \"4\" { // nobody is allowed to see the resource with id = 4\n\t\t\tctx.JSON(http.StatusNotFound, nil)\n\t\t\tctx.Abort() // do this so the request chain does not proceed\n\t\t\treturn\n\t\t}\n\t}\n\n\tupdateLastViewed := func(ctx *gin.Context) {\n\t\t// call some API to update the last viewed for this document\n\t}\n\n\tnotifyChannels := func(ctx *gin.Context) {\n\t\t// send to the websockets listening to updates on this document\n\t}\n\n\tservice, allowedMethods := rest.NewService().Get(getHandler).Service()\n\trest.With(service, allowedMethods...).\n\t\tBefore(checkAuthorization).\n\t\tAfter(updateLastViewed, notifyChannels). // notice more than one hook\n\t\tRegister(router.Group(\"/documents\"))\n}\n```\n\n### Params\n\nParams is used to hold data needed to be passed to the service. It's simply a `map[string]interface{}`. Below is an\nexample on how to interact with the params of a request [context]:\n\n```go\npackage demo\n\nimport (\n\trest \"github.com/blackmann/resteasy\"\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype query struct {\n\tname string\n\tage  int\n}\n\nfunc parseQuery(ctx *gin.Context) {\n\tparams := rest.GetParams(ctx)\n\tparams.Set(\"query\", query{name: \"Hello\", age: 23})\n}\n\nfunc getQuery(ctx *gin.Context) query {\n\treturn rest.GetParams(ctx).Get(\"query\").(query)\n}\n```\n\n## Constraints\n\nThis library does not intend to be an omnipotent library for developing rest services. Therefore, features will be\nlimited to very few options. Since this library is based on `gin`, 1. you can implement custom behavior\nwith [hooks](#hooks) or 2. implement your service from scratch. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackmann%2Fresteasy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblackmann%2Fresteasy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackmann%2Fresteasy/lists"}