{"id":30314036,"url":"https://github.com/clarify/jsoncat","last_synced_at":"2026-05-17T00:55:56.325Z","repository":{"id":57550547,"uuid":"308596055","full_name":"clarify/jsoncat","owner":"clarify","description":"Concatinate JSON objects, arrays and string","archived":false,"fork":false,"pushed_at":"2021-10-27T09:02:33.000Z","size":18,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-06-20T17:34:57.148Z","etag":null,"topics":["go","json"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clarify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-30T10:24:07.000Z","updated_at":"2024-06-20T17:34:57.149Z","dependencies_parsed_at":"2022-08-29T22:30:31.683Z","dependency_job_id":null,"html_url":"https://github.com/clarify/jsoncat","commit_stats":null,"previous_names":["searis/jsoncat"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/clarify/jsoncat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarify%2Fjsoncat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarify%2Fjsoncat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarify%2Fjsoncat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarify%2Fjsoncat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clarify","download_url":"https://codeload.github.com/clarify/jsoncat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarify%2Fjsoncat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270892212,"owners_count":24663543,"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","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"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":["go","json"],"created_at":"2025-08-17T18:56:07.215Z","updated_at":"2026-05-17T00:55:56.284Z","avatar_url":"https://github.com/clarify.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON Cat\n\n![Go](https://github.com/clarify/jsoncat/workflows/Go/badge.svg)\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/clarify/jsoncat)][pkgref]\n\nThe `jsoncat` package provide functions for concatenating JSON entities of the\nsame JSON type (object, array or string) while preserving the order of elements.\n\nSee the [package reference][pkgref] for more details and examples.\n\n[pkgref]: https://pkg.go.dev/github.com/clarify/jsoncat\n\n## Example\n\nThe following example shows a particular use-case where this library can come in\nhandy:\n\n1. You build an API client in Go.\n2. You choose to rely on [embedded structs][embedstruct] to compose your\n   models through defining some re-usable \"field sets\".\n3. You realize that some of the fields in the shared field-sets are _read-only_\n   and you get an error when writing the model back.\n4. You realize that `json.Marshal` does not look for `json.Marshaler`\n   implementation in embedded fields... Or at least not in the way you want, as\n   the method is just inherited.\n\nIf only there was an easy way to let JSON Marshaling of struct consult\npotential `json.Marshaler` implementations for embedded fields..\n\n... well, no there is with `jsoncat`:\n\n[embedstruct]: https://cwinters.com/2014/09/02/embedded_structs_in_go.html\n\n```go\nimport (\n    \"encoding/json\"\n    \"time\"\n\n    \"github.com/clarify/jsoncat\"\n)\n\n// Model is assumed a base client-side base model for resources from an API.\n// Some fields are read-only.  Since unmarshaling is case-insensitive, and we\n// implement our own MarshalJSON we don't need to specify any JSON tags\n// for this example.\ntype Model struct {\n    ID        string\n\n    CreatedBy string    // read-only field\n    UpdatedBy string    // read-only field\n    CreatedAt time.Time // read-only field\n    UpdatedAt time.Time // read-only field\n\n}\n\nfunc (m Model) MarshalJSON() ([]byte, error) {\n    // We omit the read-only fields when encoding m.\n    return json.Marshal(struct {\n        ID string `json:\"id\"`\n    }{\n        ID: m.ID,\n    })\n}\n\n// SoftDelete provides an optional field-set for models that can be\n// soft-deleted. All fields are read-write, so we don't need a custom\n// MarshalJSON implementation, and we define struct-tags to get the right case\n// when marshaling.\ntype SoftDelete struct {\n    DeletedAt *time.Time `json:\"deletedAt\"`\n    ExpiresAt *time.Time `json:\"expiresAt\"`\n}\n\n\n// User is an example Model that rely on several predefined field-sets, as well\n// as defining some fields of it's own.  Since unmarshaling is case-insensitive,\n// and we implement our own MarshalJSON we don't need to specify any JSON tags\n// for this example.\ntype User struct {\n    // By relying on embedded structs, json.Unmarshal will be able to write\n    // fields into the correct members from a flat JSON object.\n    Model\n    SoftDelete\n\n    // Non embedded fields are also correctly decoded from the flat JSON.\n    FirstName string\n    LastName  string\n}\n\nfunc (a User) MarshalJSON() ([]byte, error) {\n    // We overwrite MarshalJSON function, we can respect the json.Marshaler\n    // implementation of our embedded fields.\n    return jsoncat.MarshalObject(a.Model, a.SoftDelete, struct{\n        FirstName string `json:\"firstName\"`\n        LastName  string `json:\"lastName\"`\n    }{\n        FirstName: a.FirstName,\n        LastName:  a.LastName,\n    })\n}\n```\n\n## Performance over features\n\nThe library is aimed at decent performance and preserving the order of elements.\nThe input to functions is thus not validated to contain valid JSON. The library\nwill be able to detect if the JSON elements does not start or end with the right\ndelimiters (`[]`, `{}`, or `\"\"`), and leading and trailing whitespace will be\ntrimmed.\n\nThe library will not remove duplicated keys or entries; if you concatenate\n`{\"foo\":\"bar\"}` and `{\"foo\":\"baz\"}` the result is `{\"foo\":\"bar\",\"foo\":\"baz\"}`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarify%2Fjsoncat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclarify%2Fjsoncat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarify%2Fjsoncat/lists"}