{"id":16101618,"url":"https://github.com/bjansen/gyokuro","last_synced_at":"2026-01-22T08:32:03.430Z","repository":{"id":26376197,"uuid":"29825482","full_name":"bjansen/gyokuro","owner":"bjansen","description":"Web framework written in Ceylon 🐘","archived":false,"fork":false,"pushed_at":"2017-10-04T14:22:46.000Z","size":638,"stargazers_count":27,"open_issues_count":6,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-06T00:28:06.831Z","etag":null,"topics":["ceylon","framework","rest","web-framework"],"latest_commit_sha":null,"homepage":"http://www.gyokuro.net","language":"Ceylon","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/bjansen.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":"2015-01-25T18:35:20.000Z","updated_at":"2021-08-09T11:58:22.000Z","dependencies_parsed_at":"2022-08-28T23:20:26.610Z","dependency_job_id":null,"html_url":"https://github.com/bjansen/gyokuro","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/bjansen/gyokuro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjansen%2Fgyokuro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjansen%2Fgyokuro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjansen%2Fgyokuro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjansen%2Fgyokuro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bjansen","download_url":"https://codeload.github.com/bjansen/gyokuro/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjansen%2Fgyokuro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28659518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ceylon","framework","rest","web-framework"],"created_at":"2024-10-09T18:50:29.604Z","updated_at":"2026-01-22T08:32:03.397Z","avatar_url":"https://github.com/bjansen.png","language":"Ceylon","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gyokuro [![Travis](https://travis-ci.org/bjansen/gyokuro.svg?branch=master)](https://travis-ci.org/bjansen/gyokuro) [![Gitter](https://badges.gitter.im/bjansen/gyokuro.svg)](https://gitter.im/bjansen/gyokuro)\n\nA web framework written in Ceylon, which allows:\n\n* routing GET/POST requests to simple `(Request, Response)` handlers\n* creating annotated controllers containing more powerful handlers\n* serving static assets (HTML, CSS, JS, ...) from a directory\n\ngyokuro is based on the [Ceylon SDK](http://github.com/ceylon/ceylon-sdk), \nand uses `ceylon.net`'s server API.\n\n## Creating a simple webapp\n\nCreate a new Ceylon module:\n\n```ceylon\nmodule gyokuro.demo.rest \"1.0.0\" {\n    import net.gyokuro.core \"0.2\";\n    import ceylon.net \"1.3.1\";\n}\n```\n\nAdd a runnable top level function that bootstraps a gyokuro application:\n\n```ceylon\nimport net.gyokuro.core {\n    Application,\n    get,\n    post,\n    serve\n}\n\n\"Run an HTTP server listening on port 8080, that will react to requests on /hello.\nStatic assets will be served from the `assets` directory.\"\nshared void run() {\n\n    // React to GET/POST requests using a basic handler\n    get(\"/hello\", void (Request request, Response response) {\n        response.writeString(\"Hello yourself!\");\n    });\n    \n    // Shorter syntax that lets Ceylon infer types and lets gyokuro\n    // write the response\n    post(\"/hello\", (request, response) =\u003e \"You're the POST master!\");\n\n    value app = Application {\n        assets = serve(\"assets\");\n    };\n    \n    app.run();\n}\n```\n\n## Binding parameters\n\nIn addition to basic handlers, gyokuro allows you to bind GET/POST data\ndirectly to function parameters, and return an object that represents your response:\n\n```ceylon\nshared void run() {\n    // ...\n    post(\"/hello\", `postHandler`);\n    // ...\n}\n\n\"Advanced handlers have more flexible parameters, you're\n not limited to `Request` and `Response`, you can bind\n GET/POST values directly to handler parameters!\n The returned value will be written to the response.\"\nString postHandler(Float float, Integer? optionalInt, String who = \"world\") {\n    // `float` is required, `optionalInt` is optional and\n    // `who` will be defaulted to \"world\" if it's not in POST data.\n    return \"Hello, \" + who + \"!\\n\";\n}\n```\n\nGET/POST values are mapped by name and automatically converted to the correct type.\nNote that optional types and default values are also supported!\n\n## Using annotated controllers\n\nIn addition to `get` and `post` functions, gyokuro supports annotated controllers.\nUsing annotations, you can easily group related handlers in a same controller.\n\nLet's see how it works on a simple example:\n\n```ceylon\nshared void run() {\n\n    value app = Application {\n        // You can use REST-style annotated controllers like this:\n        controllers = bind(`package gyokuro.demo.rest`, \"/rest\");\n    };\n    \n    app.run();\n}\n```\n\nThe package `gyokuro.demo.rest` will be scanned for classes annotated with `controller`.\nEach function annotated with `route` will be mapped to the corresponding path. For example:\n\n```ceylon\nimport ceylon.net.http.server {\n    Response\n}\nimport net.gyokuro.core {\n    controller,\n    route\n}\n\nroute(\"duck\")\ncontroller class SimpleRestController() {\n    \n    route(\"talk\")\n    shared void makeDuckTalk(Response resp) {\n        resp.writeString(\"Quack world!\");\n    }\n}\n```\n\nWill be mapped to `http://localhost:8080/rest/duck/talk`.\n\n## Want to learn more?\n\nSee the [complete documentation](http://bjansen.github.io/gyokuro/doc/0.2/) for more info.\n\nYou can find examples in the [demos directory](https://github.com/bjansen/gyokuro/tree/master/demos/).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjansen%2Fgyokuro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbjansen%2Fgyokuro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjansen%2Fgyokuro/lists"}