{"id":22525050,"url":"https://github.com/andrewpillar/webutil","last_synced_at":"2025-08-03T21:32:07.759Z","repository":{"id":40271347,"uuid":"312416768","full_name":"andrewpillar/webutil","owner":"andrewpillar","description":"Utility package for web development in Go","archived":false,"fork":false,"pushed_at":"2023-04-30T15:56:07.000Z","size":69,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-21T00:16:04.397Z","etag":null,"topics":["go","http","web-development"],"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/andrewpillar.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":"2020-11-12T23:02:24.000Z","updated_at":"2023-12-18T07:05:09.000Z","dependencies_parsed_at":"2024-06-20T23:27:06.760Z","dependency_job_id":"03b2e912-3e04-42cf-b2a6-ecce26c88553","html_url":"https://github.com/andrewpillar/webutil","commit_stats":{"total_commits":21,"total_committers":2,"mean_commits":10.5,"dds":0.09523809523809523,"last_synced_commit":"1c29fece2152f31e0396cfde33564c22f93308bf"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fwebutil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fwebutil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fwebutil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewpillar%2Fwebutil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewpillar","download_url":"https://codeload.github.com/andrewpillar/webutil/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228567027,"owners_count":17937986,"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":["go","http","web-development"],"created_at":"2024-12-07T06:08:05.416Z","updated_at":"2024-12-07T06:08:05.989Z","avatar_url":"https://github.com/andrewpillar.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# webutil\n\nwebutil is a collection of utility functions to aid in the development of web\napplications in Go. this builds on top of some packages provided by the\n[Gorilla web toolkit][0] such as [gorilla/schema][1] and [gorilla/sessions][2].\n\nThis package provides the ability to easily handle form validation, file\nuploads, serving different content types, and flashing of form data between\nrequests.\n\n## Examples\n\n**Form Validation**\n\nForm validations is achieved via the `webutil.Form` and `webutil.Validator`\ninterfaces. The `webutil.Form` interface wraps the `Fields` method that returns\na map of the underlying fields in the form. The `webutil.Validator` interface\nwraps the `Validate` method for validating data. Below is an example of these\ninterfaces being implemented for form validation,\n\n    type LoginForm struct {\n        Email    string\n        Password string\n    }\n\n    func (f LoginForm) Fields() map[string]string {\n        return map[string]string{\n            \"email\": f.Email,\n        }\n    }\n\n    type LoginValidator struct {\n        Form Login\n    }\n\n    func (v LoginValidator) Validate(errs webutil.ValidationErrors) error {\n        if f.Email == \"\" {\n            errs.Add(\"email\", webutil.ErrFieldRequired(\"email\"))\n        }\n        if f.Password == \"\" {\n            errs.Add(\"password\", webutil.ErrFieldRequired(\"password\"))\n        }\n    }\n\nwith the above implementation we can then use `webutil.UnmarshalForm` and\n`webutil.Validate` to unmarshal and validate the form data,\n\n    func Login(w http.ResponseWriter, r *http.Request) {\n        var f LoginForm\n\n        if err := webutil.UnmarshalForm(\u0026f, r); err != nil {\n            io.WriteString(w, err.Error())\n            return\n        }\n\n        v := LoginValidator{\n            Form: f,\n        }\n\n        if err := webutil.Validate(v); err != nil {\n            io.WriteString(w, err.Error())\n            return\n        }\n    }\n\n`webutil.Validate` will always return the `webutil.ValidationErrors` error\ntype. Under the hood the [gorilla/schema][1] package is used to handle the\nunmarshalling of request data into a form.\n\n**File Uploads**\n\nFile uploads can be handled via the `webutil.File` type. This can be used along\nthe `webutil.FileValidator` to handle the uploading and validating of files,\n\n    type UploadForm struct {\n        File *webutil.File\n        Name string\n    }\n\n    func Upload(w http.ResponseWriter, r *http.Request) {\n        f := UploadForm{\n            File: \u0026webutil.File{\n                Field: \"avatar\",\n            },\n        }\n\n        if err := webutil.UnmarshalFormWithFile(\u0026f, f.File, r); err != nil {\n            io.WriteString(w, err.Error())\n            return\n        }\n\n        defer f.File.Remove()\n\n        v := \u0026webutil.FileValidator{\n            File: f.File,\n            Size: 5 * (1 \u003c\u003c 20),\n        }\n\n        if err := webutil.Validate(v); err != nil {\n            io.WriteString(w, err.Error())\n            return\n        }\n\n        dir, _ := os.Getwd()\n        dst, _ := os.CreateTemp(dir, \"\")\n\n        io.Copy(dst, f.File)\n\n        w.WriteHeader(http.StatusNoContent)\n    }\n\nwith the above example, we call the `webutil.UnmarshalFormWithFile` function to\nhandle the unmarshalling of the file from the request. This will also handle\nrequests where the file is sent as the request body itself, when this is done\nthe URL query parameters are used as the typical form values. Validation of the\nfile is then handled with the `webutil.FileValidator`.\n\n**Response Types**\n\nHTML, Text, and JSON response types can be sent using the respective functions\nprovided by this package. These functions will set the appropriate\n`Content-Type` header, and `Content-Length` too.\n\n    func HTMLHandler(w http.ResponseWriter, r *http.Request) {\n        webutil.HTML(w, \"\u003ch1\u003eHTML response\u003c/h1\u003e\", http.StatusOK)\n    }\n\n    func TextHandler(w http.ResponseWriter, r *http.Request) {\n        webutil.Text(w, \"Text response\", http.StatusOK)\n    }\n\n    func JSONHandler(w http.ResponseWriter, r *http.Request) {\n        data := map[string]string{\n            \"message\": \"JSON response\",\n        }\n        webutil.JSON(w, data, http.StatusOK)\n    }\n\n[0]: https://www.gorillatoolkit.org\n[1]: https://github.com/gorilla/schema\n[2]: https://github.com/gorilla/sessions\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewpillar%2Fwebutil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewpillar%2Fwebutil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewpillar%2Fwebutil/lists"}