{"id":13476359,"url":"https://github.com/tminglei/form-binder","last_synced_at":"2026-08-16T15:31:22.427Z","repository":{"id":20424526,"uuid":"23701049","full_name":"tminglei/form-binder","owner":"tminglei","description":"A micro data binding and validating framework, very easy to use and hack","archived":false,"fork":false,"pushed_at":"2016-10-05T05:39:19.000Z","size":975,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-29T20:57:58.458Z","etag":null,"topics":["data-binding","data-validation"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tminglei.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":"2014-09-05T11:42:47.000Z","updated_at":"2024-10-25T16:06:20.000Z","dependencies_parsed_at":"2022-07-31T19:18:09.190Z","dependency_job_id":null,"html_url":"https://github.com/tminglei/form-binder","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/tminglei/form-binder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tminglei%2Fform-binder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tminglei%2Fform-binder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tminglei%2Fform-binder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tminglei%2Fform-binder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tminglei","download_url":"https://codeload.github.com/tminglei/form-binder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tminglei%2Fform-binder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36718482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-08-06T04:43:03.162Z","status":"online","status_checked_at":"2026-08-16T02:00:06.462Z","response_time":62,"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":["data-binding","data-validation"],"created_at":"2024-07-31T16:01:29.350Z","updated_at":"2026-08-16T15:31:22.405Z","avatar_url":"https://github.com/tminglei.png","language":"Scala","funding_links":[],"categories":["Scala","Data Binding and Validation"],"sub_categories":[],"readme":"form-binder\n===========\n[![Build Status](https://travis-ci.org/tminglei/form-binder.svg?branch=master)](https://travis-ci.org/tminglei/form-binder)\n\n\nForm-binder is a micro data binding and validating framework, very easy to use and hack.\n\n\u003e _It was initially created for my [`Scalatra`](https://github.com/scalatra/scalatra)-based project, but you can easily integrate it with other frameworks._\n\n\n\nFeatures\n-------------\n- very lightweight, only ~900 lines codes (framework + built-in extensions)\n- easy use, no verbose codes, and what you see is what you get\n- high customizable, you can extend almost every executing point\n- easily extensible, every extension interface is an alias of `FunctionN`\n- immutable, you can share mapping definition object safely\n\n\n\nUsage\n-------------\n![form-binder description](https://github.com/tminglei/form-binder/raw/master/form-binder-desc.png)\n\nSteps:  \n 1. define your binder  \n 2. define your mappings  \n 3. prepare your data  \n 4. bind and consume  \n\n\n\u003e _p.s. every points above (1)/(2)/(3)/(4)/ are all extendable and you can easily customize it._  \n\n\n\nInstall \u0026 Integrate\n--------------------\nTo use `form-binder`, pls add the dependency to your [sbt](http://www.scala-sbt.org/ \"slick-sbt\") project file:\n```scala\nlibraryDependencies += \"com.github.tminglei\" %% \"form-binder\" % \"0.12.2\"\n```\n\nThen you can integrate it with your framework to simplify normal usage. \n\nHere's the way in my `Scalatra` project:\n\nFirst, I defined a `FormBindSupport` trait,\n```scala\ntrait MyFormBindSupport extends I18nSupport { self: ScalatraBase =\u003e\n  import MyFormBindSupport._\n\n  before() {\n    request(BindMessagesKey) = Messages(locale, bundlePath = \"bind-messages\")\n  }\n\n  def binder(implicit request: HttpServletRequest) = FormBinder(bindMessages.get, errsTree())\n\n  ///\n  private def bindMessages(implicit request: HttpServletRequest): Messages = if (request == null) {\n    throw new ScalatraException(\"There needs to be a request in scope to call bindMessages\")\n  } else {\n    request.get(BindMessagesKey).map(_.asInstanceOf[Messages]).orNull\n  }\n}\n```\nThen mix it to my xxxServlet, and use it like this,\n```scala\nimport com.github.tminglei.bind.simple._\n\nclass SampleServlet extends ScalatraServlet with MyFormBindSupport {\n\n  get(\"/:id\") {\n    val mappings = tmapping(\n      \"id\" -\u003e long()\n    )\n    binder.bind(mappings, params).fold(\n      errors =\u003e holt(400, errors),\n      { case (id) =\u003e\n        Ok(toJson(repos.features.get(id)))\n      }\n    )\n  }\n}\n```\n\n_p.s. you can check more integration sample codes under  [/integrations](https://github.com/tminglei/form-binder/tree/master/integrations)._\n\n\nHow it works\n--------------------\n### Principle\nThe core of `form-binder` is `Mapping`, **tree structure** mappings. With **depth-first** algorithm, it was used to validate data and construct the result value object.\n\n### Details\n\n![form-binder description](https://github.com/tminglei/form-binder/raw/master/form-binder-desc.png)\n\n#### Major Components:  \n[1] **binder**: facade, used to bind and trigger processing, two major methods: `bind`, `validate`  \n[2] **messages**: used to provide error messages  \n[3] **mapping**: holding constraints, processors, and maybe child mapping, etc. used to validate/convert data, two types of mappings: `field` and `group`  \n[4] **data**: inputting data map  \n\n\u003e _Check [here](https://github.com/tminglei/form-binder/blob/master/src/main/scala/com/github/tminglei/bind/package.scala) and [here](https://github.com/tminglei/form-binder/blob/master/src/main/scala/com/github/tminglei/bind/Framework.scala) for framework details._\n\nbinder **bind** method signature (return an `Either` and let user to continue processing):\n```scala\n//bind mappings to data, and return an either, holding validation errors (left) or converted value (right)\ndef bind[T](mapping: Mapping[T], data: Map[String, String], root: String = \"\"): Either[R, T]\n```\n\nbinder **validate** method signature (_validate only_ and not consume converted data):\n```scala\n//return (maybe processed) errors\ndef validate[T](mapping: Mapping[T], data: Map[String, String], root: String = \"\")\n```\n\n\u003e _Check [here](https://github.com/tminglei/form-binder/blob/master/src/main/scala/com/github/tminglei/bind/Mappings.scala) for built-in **mapping**s._  \n\n#### Extension Types:  \n(1) **ErrProcessor**: used to process error seq, like converting it to json  \n(2) **PreProcessor**: used to pre-process data, like omitting `$` from `$3,013`  \n(3) **Constraint**: used to validate raw string data  \n(4) **ExtraConstraint**: used to validate converted value\n\n\u003e _* Check [here](https://github.com/tminglei/form-binder/blob/master/src/main/scala/com/github/tminglei/bind/Processors.scala) for built-in `PreProcessor`/`ErrProcessor`._  \n\u003e _**Check [here](https://github.com/tminglei/form-binder/blob/master/src/main/scala/com/github/tminglei/bind/Constraints.scala) for built-in `Constraint`/`ExtraConstraint`._\n\n#### Options/Features:  \n1) **label**: `feature`, readable name for current group/field  \n2) **mapTo**: `feature`, map converted value to another type  \n3) **i18n**: `feature`, labels starting with `@` will be used as a message key to fetch a i18n value from `messages`  \n4) **eagerCheck**: `option`, check errors as more as possible; default `false`, return right after a validation error found  \n5) **skipUntouched**: `option`, skip checking untouched empty field/values; default `false`, won't skip untouched  \n6) **touchedChecker**: `function`, check whether a field was touched by user; if yes, required fields can't be empty\n\n\n_p.s. for more dev and usage details, pls check the [source codes](https://github.com/tminglei/form-binder/tree/master/src/main/scala/com/github/tminglei/bind) and [test cases](https://github.com/tminglei/form-binder/tree/master/src/test/scala/com/github/tminglei/bind)._\n\n\n\nHow to\n--------------------\n[TODO]\n\n\n\nBuild \u0026 Test\n-------------------\nTo hack it and make your contribution, you can setup it like this:\n```bash\n $ git clone https://github.com/tminglei/form-binder.git\n $ cd form-binder\n $ sbt\n...\n```\nTo run the tests, pls execute:\n```bash\n $ sbt test\n```\n\n\n\nAcknowledgements\n-----------------\n- [`Play!`](https://github.com/playframework/playframework) framework development team, for the original idea and implementation;\n- [Naoki Takezoe](https://github.com/takezoe) and his [`scalatra-forms`](https://github.com/takezoe/scalatra-forms), a `play-data` implementation for scalatra.\n\n\nLicense\n---------\nThe BSD License, Minglei Tu \u0026lt;tmlneu@gmail.com\u0026gt;\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftminglei%2Fform-binder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftminglei%2Fform-binder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftminglei%2Fform-binder/lists"}