{"id":20935899,"url":"https://github.com/pooulad/cherry","last_synced_at":"2025-05-13T21:30:50.183Z","repository":{"id":213539206,"uuid":"732458851","full_name":"pooulad/cherry","owner":"pooulad","description":"🍒Cherry is a web framework for Go language.","archived":false,"fork":false,"pushed_at":"2024-12-09T17:34:13.000Z","size":143,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T08:08:43.942Z","etag":null,"topics":["backend","go","golang","golang-package","web-api","web-framework","web-server","webframework","webser"],"latest_commit_sha":null,"homepage":"","language":"Go","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/pooulad.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-16T18:35:14.000Z","updated_at":"2024-12-12T10:42:11.000Z","dependencies_parsed_at":"2023-12-21T16:37:59.297Z","dependency_job_id":"d30e668d-26be-4b62-9f3b-87eb796e22e3","html_url":"https://github.com/pooulad/cherry","commit_stats":null,"previous_names":["pooulad/cherry"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pooulad%2Fcherry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pooulad%2Fcherry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pooulad%2Fcherry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pooulad%2Fcherry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pooulad","download_url":"https://codeload.github.com/pooulad/cherry/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254030853,"owners_count":22002661,"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":["backend","go","golang","golang-package","web-api","web-framework","web-server","webframework","webser"],"created_at":"2024-11-18T22:16:44.072Z","updated_at":"2025-05-13T21:30:49.760Z","avatar_url":"https://github.com/pooulad.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cherry🍒 [![Go](https://img.shields.io/badge/--00ADD8?logo=go\u0026logoColor=ffffff)](https://golang.org/)\n\n🚨Cherry🍒 is a web framework for Go language.\n\n## Installation\n```go\ngo get github.com/pooulad/cherry\n```\n## Features\n\n- fast route dispatching backed by http-router\n- easy to add middleware handlers\n- sub-routing with separated middleware handlers\n- central based error handling\n- build in template engine\n- fast, lightweight and extendable\n\n## Basic usage\n\n```go\npackage main\nimport \"github.com/pooulad/cherry\"\n\nfunc main() {\n    app := cherry.New()\n\n    app.Get(\"/foo\", fooHandler)\n    app.Post(\"/bar\", barHandler)\n    app.Use(middleware1, middleware2)\n\n    friends := app.Group(\"/friends\")\n    friends.Get(\"/profile\", profileHandler)\n    friends.Use(middleware3, middleware4)\n    \n    app.Serve(8080)\n}\n```\nMore complete examples can be found in the examples folder\n\n## Routes\n\n```go\napp := cherry.New()\n\napp.Get(\"/\", func(ctx *cherry.Context) error {\n   .. do something .. \n})\napp.Post(\"/\", func(ctx *cherry.Context) error {\n   .. do something .. \n})\napp.Put(\"/\", func(ctx *cherry.Context) error {\n   .. do something .. \n})\napp.Delete(\"/\", func(ctx *cherry.Context) error {\n   .. do something .. \n})\n```\nget named url parameters\n\n```go\napp.Get(\"/hello/:name\", func(ctx *cherry.Context) error {\n    name := ctx.Param(\"name\")\n})\n```\n\n## Group (subrouting)\n\nGroup lets you manage routes, contexts and middleware separate from each other.\n\nCreate a new cherry object and attach some middleware and context to it.\n\n```go\napp := cherry.New()\napp.BindContext(context.WithValue(context.Background(), \"foo\", \"bar\")\napp.Get(\"/\", somHandler)\napp.Use(middleware1, middleware2)\n```\n\nCreate a group and attach its own middleware and context to it\n\n```go\nfriends := app.Group(\"/friends\")\napp.BindContext(context.WithValue(context.Background(), \"friend1\", \"john\")\nfriends.Post(\"/create\", someHandler)\nfriends.Use(middleware3, middleware4)\n```\nIn this case group friends will inherit middleware1 and middleware2 from its parent app. We can reset the middleware from its parent by calling ```Reset()```\n\n```go\nfriends := app.Group(\"/friends\").Reset()\nfriends.Use(middleware3, middleware4)\n```\nNow group friends will have only middleware3 and middleware4 attached.\n\n## Static files\nMake our assets are accessible trough /assets/styles.css\n\n```go\napp := cherry.New()\napp.Static(\"/assets\", \"public/assets\")\n```\n\n## Handlers\n### A definition of a cherry.Handler\n\n```go\nfunc(ctx *cherry.Context) error\n```\n\nCherry only accepts handlers of type ```cherry.Handler``` to be passed as functions in routes. You can convert any type of handler to a ```cherry.Handler```.\n\n```go\nfunc myHandler(name string) cherry.Handler{\n    .. do something ..\n   return func(ctx *cherry.Context) error {\n        return ctx.Text(w, http.StatusOK, name)\n   }\n}\n```\n\n### Returning errors\nEach handler requires an error to be returned. This is personal idiom but it brings some benefits for handling your errors inside request handlers.\n\n```go\nfunc someHandler(ctx *cherry.Context) error {\n    // simple error handling by returning all errors \n    err := someFunc(); err != nil {\n        return err\n    }\n    ...\n    req, err := http.NewRequest(...)\n    if err != nil {\n        return err\n    }\n}\n```\n\nA cherry ErrorHandlerFunc\n\n```go\nfunc(ctx *cherry.Context, err error)\n```\n\nHandle all errors returned by adding a custom errorHandler for our application.\n\n```go\napp := cherry.New()\nerrHandler := func(ctx *cherry.Context, err error) {\n    .. handle the error ..\n}\napp.SetErrorHandler(errHandler)\n```\n\n## Context\nContext is a request based object helping you with a series of functions performed against the current request scope.\n\n### Passing values around middleware functions\nContext provides a context.Context for passing request scoped values around middleware functions.\n\nCreate a new context and pass some values\n\n```go\nfunc someMiddleware(ctx *cherry.Context) error {\n    ctx.Context = context.WithValue(ctx.Context, \"foo\", \"bar\")\n    return someMiddleware2(ctx)\n}\n```\n\nGet the value back from the context in another middleware function\n\n```go\nfunc someMiddleware2(ctx *cherry.Context) error {\n    value := ctx.Context.Value(\"foo\").(string)\n    ..\n}\n```\n\n### Binding a context\nIn some cases you want to initialize a context from the the main function, like a datastore for example. You can set a context out of a request scope by calling ```BindContext()```.\n\n```go\napp.BindContext(context.WithValue(context.Background(), \"foo\", \"bar\"))\n```\n\nAs mentioned in the Group section, you can add different contexts to different groups.\n\n```go\nmyGroup := app.Group(\"/foo\", ..)\nmyGroup.BindContext(..)\n```\n\n### Helper functions\nContext also provides a series of helper functions like responding JSON en text, JSON decoding etc..\n\n```go\nfunc createUser(ctx *cherry.Context) error {\n    user := model.User{}\n    if err := ctx.DecodeJSON(\u0026user); err != nil {\n        return errors.New(\"failed to decode the response body\")\n    }\n    ..\n    return ctx.JSON(http.StatusCreated, user)\n}\n\nfunc login(ctx *cherry.Context) error {\n    token := ctx.Header(\"x-hmac-token\")\n    if token == \"\" {\n        ctx.Redirect(\"/login\", http.StatusMovedPermanently)\n        return nil\n    }\n    ..\n}\n```\n\n## Logging\n\n### Access Log\n\nCherry provides an access-log in an Apache log format for each incoming request. The access-log is disabled by default, to enable the access-log set ```app.HasAccessLog = true```.\n\n```\n127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326\n```\n\n## Server\nCherry HTTP server is a wrapper around the default std HTTP server, the only difference is that it provides a graceful shutdown. Cherry provides both HTTP and HTTPS (TLS).\n\n```go\napp := cherry.New()\napp.ServeTLS(8080, cert, key)\n// or \napp.Serve(8080)\n```\n### Gracefull stopping a cherry app\n\nGracefull stopping a cherry app is done by sending one of these signals to the process.\n\n- SIGINT\n- SIGQUIT\n- SIGTERM\n\nYou can also force-quit your app by sending it SIGKILL signal\n\nSIGUSR2 signal is not yet implemented. Reloading a new binary by forking the main process is something that wil be implemented when the need for it is there. Feel free to give some feedback on this feature if you think it can provide a bonus to the package.\n\n## Screenshots\n\n![App Screenshot](https://github.com/pooulad/cherry/blob/main/assets/images/test_app.png)\n\n![App Screenshot](https://github.com/pooulad/cherry/blob/main/asstes/images/start_app.png)\n\n\n## Support\n\nIf you like Cherry🍒 buy me a coffee☕ or star project🌟\n\n\u003ca href=\"https://www.coffeebede.com/poulad\"\u003e\u003cimg size=\"small\" class=\"img-fluid\" src=\"https://coffeebede.ir/DashboardTemplateV2/app-assets/images/banner/default-yellow.svg\" /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpooulad%2Fcherry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpooulad%2Fcherry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpooulad%2Fcherry/lists"}