{"id":18994071,"url":"https://github.com/swaggest/jsonschema-go","last_synced_at":"2025-05-15T18:08:51.001Z","repository":{"id":40435747,"uuid":"223887579","full_name":"swaggest/jsonschema-go","owner":"swaggest","description":"JSON Schema mapping for Go","archived":false,"fork":false,"pushed_at":"2025-01-20T21:01:14.000Z","size":328,"stargazers_count":139,"open_issues_count":7,"forks_count":15,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T23:33:39.011Z","etag":null,"topics":["code-generation","hacktoberfest","json-schema"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/swaggest/jsonschema-go","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/swaggest.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":"2019-11-25T07:30:35.000Z","updated_at":"2025-03-14T18:32:59.000Z","dependencies_parsed_at":"2023-02-10T16:00:40.929Z","dependency_job_id":"e5841097-029e-4b21-a00d-9796e361a774","html_url":"https://github.com/swaggest/jsonschema-go","commit_stats":{"total_commits":103,"total_committers":8,"mean_commits":12.875,"dds":"0.30097087378640774","last_synced_commit":"524f24bbcc31d5436ca3ba6f67a6f4454902162d"},"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggest%2Fjsonschema-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggest%2Fjsonschema-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggest%2Fjsonschema-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggest%2Fjsonschema-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swaggest","download_url":"https://codeload.github.com/swaggest/jsonschema-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247755557,"owners_count":20990620,"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":["code-generation","hacktoberfest","json-schema"],"created_at":"2024-11-08T17:24:04.961Z","updated_at":"2025-05-15T18:08:50.995Z","avatar_url":"https://github.com/swaggest.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON Schema structures for Go\n\n\u003cimg align=\"right\" width=\"100px\" src=\"https://avatars0.githubusercontent.com/u/13019229?s=200\u0026v=4\"\u003e\n\n[![Build Status](https://github.com/swaggest/jsonschema-go/workflows/test-unit/badge.svg)](https://github.com/swaggest/jsonschema-go/actions?query=branch%3Amaster+workflow%3Atest-unit)\n[![Coverage Status](https://codecov.io/gh/swaggest/jsonschema-go/branch/master/graph/badge.svg)](https://codecov.io/gh/swaggest/jsonschema-go)\n[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/swaggest/jsonschema-go)\n[![time tracker](https://wakatime.com/badge/github/swaggest/jsonschema-go.svg)](https://wakatime.com/badge/github/swaggest/jsonschema-go)\n![Code lines](https://sloc.xyz/github/swaggest/jsonschema-go/?category=code)\n![Comments](https://sloc.xyz/github/swaggest/jsonschema-go/?category=comments)\n\nThis library provides Go structures to marshal/unmarshal and reflect [JSON Schema](https://json-schema.org/) documents.\n\n## Reflector\n\n[Documentation](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Reflector.Reflect).\n\n```go\ntype MyStruct struct {\n    Amount float64  `json:\"amount\" minimum:\"10.5\" example:\"20.6\" required:\"true\"`\n    Abc    string   `json:\"abc\" pattern:\"[abc]\"`\n    _      struct{} `additionalProperties:\"false\"`                   // Tags of unnamed field are applied to parent schema.\n    _      struct{} `title:\"My Struct\" description:\"Holds my data.\"` // Multiple unnamed fields can be used.\n}\n\nreflector := jsonschema.Reflector{}\n\nschema, err := reflector.Reflect(MyStruct{})\nif err != nil {\n    log.Fatal(err)\n}\n\nj, err := json.MarshalIndent(schema, \"\", \" \")\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Println(string(j))\n\n// Output:\n// {\n//  \"title\": \"My Struct\",\n//  \"description\": \"Holds my data.\",\n//  \"required\": [\n//   \"amount\"\n//  ],\n//  \"additionalProperties\": false,\n//  \"properties\": {\n//   \"abc\": {\n//    \"pattern\": \"[abc]\",\n//    \"type\": \"string\"\n//   },\n//   \"amount\": {\n//    \"examples\": [\n//     20.6\n//    ],\n//    \"minimum\": 10.5,\n//    \"type\": \"number\"\n//   }\n//  },\n//  \"type\": \"object\"\n// }\n```\n\n## Customization\n\nBy default, JSON Schema is generated from Go struct field types and tags.\nIt works well for the majority of cases, but if it does not there are rich customization options.\n\n### Field tags\n\n```go\ntype MyObj struct {\n   BoundedNumber int `query:\"boundedNumber\" minimum:\"-100\" maximum:\"100\"`\n   SpecialString string `json:\"specialString\" pattern:\"^[a-z]{4}$\" minLength:\"4\" maxLength:\"4\"`\n}\n```\n\nNote: field tags are only applied to inline schemas, if you use named type then referenced schema\nwill be created and tags will be ignored. This happens because referenced schema can be used in\nmultiple fields with conflicting tags, therefore customization of referenced schema has to done on\nthe type itself via `RawExposer`, `Exposer` or `Preparer`.\n\nEach tag value has to be put in double quotes (`\"123\"`).\n\nThese tags can be used:\n* [`title`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.6.1), string\n* [`description`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.6.1), string\n* [`default`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.6.2), can be scalar or JSON value\n* [`example`](https://json-schema.org/draft/2020-12/json-schema-validation.html#name-examples), a scalar value that matches type of parent property, for an array it is applied to items\n* [`examples`](https://json-schema.org/draft/2020-12/json-schema-validation.html#name-examples), a JSON array value\n* [`const`](https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.1.3), can be scalar or JSON value\n* [`deprecated`](https://json-schema.org/draft/2020-12/json-schema-validation#name-deprecated), boolean\n* [`readOnly`](https://json-schema.org/draft/2020-12/json-schema-validation#name-deprecated), boolean\n* [`writeOnly`](https://json-schema.org/draft/2020-12/json-schema-validation#name-deprecated), boolean\n* [`pattern`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.2.3), string\n* [`format`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.7), string\n* [`multipleOf`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.1.1), float \u003e 0\n* [`maximum`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.1.2), float\n* [`minimum`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.1.3), float\n* [`maxLength`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.2.1), integer\n* [`minLength`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.2.2), integer\n* [`maxItems`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.3.2), integer\n* [`minItems`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.3.3), integer\n* [`maxProperties`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.4.1), integer\n* [`minProperties`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.4.2), integer\n* [`exclusiveMaximum`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.1.2), boolean\n* [`exclusiveMinimum`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.1.3), boolean\n* [`uniqueItems`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.3.4), boolean\n* [`enum`](https://json-schema.org/draft-04/json-schema-validation.html#rfc.section.5.5.1), tag value must be a JSON or comma-separated list of strings\n* `required`, boolean, marks property as required\n* `nullable`, boolean, overrides nullability of the property\n\nUnnamed fields can be used to configure parent schema:\n\n```go\ntype MyObj struct {\n   BoundedNumber int `query:\"boundedNumber\" minimum:\"-100\" maximum:\"100\"`\n   SpecialString string `json:\"specialString\" pattern:\"^[a-z]{4}$\" minLength:\"4\" maxLength:\"4\"`\n   _             struct{} `additionalProperties:\"false\" description:\"MyObj is my object.\"`\n}\n```\n\nIn case of a structure with multiple name tags, you can enable filtering of unnamed fields with\nReflectContext.UnnamedFieldWithTag option and add matching name tags to structure (e.g. query:\"_\").\n\n```go\ntype MyObj struct {\n   BoundedNumber int `query:\"boundedNumber\" minimum:\"-100\" maximum:\"100\"`\n   SpecialString string `json:\"specialString\" pattern:\"^[a-z]{4}$\" minLength:\"4\" maxLength:\"4\"`\n   // These parent schema tags would only be applied to `query` schema reflection (not for `json`).\n   _ struct{} `query:\"_\" additionalProperties:\"false\" description:\"MyObj is my object.\"`\n}\n```\n\nComplex nested maps and slices/arrays can be configured with path-prefixed field tags.\n\n```go\ntype MyObj struct {\n\tInts          []int            `json:\"ints\" items.title:\"My int\"`\n\tExtraFloats   [][]float64      `json:\"extra_floats\" items.items.title:\"My float\" items.items.enum:\"1.23,4.56\"`\n\tMappedStrings map[int]string   `json:\"mapped_strings\" additionalProperties.enum:\"abc,def\"`\n\tVeryDeep      map[int][]string `json:\"very_deep\" additionalProperties.items.enum:\"abc,def\"`\n}\n```\n\n### Implementing interfaces on a type\n\nThere are a few interfaces that can be implemented on a type to customize JSON Schema generation.\n\n* [`Preparer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Preparer) allows to change generated JSON Schema.\n* [`Exposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Exposer) overrides generated JSON Schema.\n* [`RawExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#RawExposer) overrides generated JSON Schema.\n* [`Described`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Described) exposes description.\n* [`Titled`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Titled) exposes title.\n* [`Enum`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Enum) exposes enum values.\n* [`NamedEnum`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#NamedEnum) exposes enum values with names.\n* [`SchemaInliner`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#SchemaInliner) inlines schema without creating a definition.\n* [`IgnoreTypeName`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#IgnoreTypeName), when implemented on a mapped type forces the use of original type for definition name.\n* [`EmbedReferencer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#EmbedReferencer), when implemented on an embedded field type, makes an `allOf` reference to that type definition.\n\nAnd a few interfaces to expose subschemas (`anyOf`, `allOf`, `oneOf`, `not` and `if`, `then`, `else`).\n* [`AnyOfExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#AnyOfExposer) exposes `anyOf` subschemas.\n* [`AllOfExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#AllOfExposer) exposes `allOf` subschemas.\n* [`OneOfExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#OneOfExposer) exposes `oneOf` subschemas.\n* [`NotExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#NotExposer) exposes `not` subschema.\n* [`IfExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#IfExposer) exposes `if` subschema.\n* [`ThenExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#ThenExposer) exposes `then` subschema.\n* [`ElseExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#ElseExposer) exposes `else` subschema.\n\nThere are also helper functions \n[`jsonschema.AllOf`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#AllOf), \n[`jsonschema.AnyOf`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#AnyOf), \n[`jsonschema.OneOf`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#OneOf) \nto create exposer instance from multiple values.\n\n\n\n### Configuring the reflector\n\nAdditional centralized configuration is available with \n[`jsonschema.ReflectContext`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#ReflectContext) and \n[`Reflect`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#Reflector.Reflect) options.\n\n* [`CollectDefinitions`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#CollectDefinitions) disables definitions storage in schema and calls user function instead.\n* [`DefinitionsPrefix`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#DefinitionsPrefix) sets path prefix for definitions.\n* [`PropertyNameTag`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#PropertyNameTag) allows using field tags other than `json`.\n* [`InterceptSchema`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#InterceptSchema) called for every type during schema reflection.\n* [`InterceptProp`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#InterceptProp) called for every property during schema reflection.\n* [`InlineRefs`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#InlineRefs) tries to inline all references (instead of creating definitions).\n* [`RootNullable`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#RootNullable) enables nullability of root schema.\n* [`RootRef`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#RootRef) converts root schema to definition reference.\n* [`StripDefinitionNamePrefix`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#StripDefinitionNamePrefix) strips prefix from definition name.\n* [`PropertyNameMapping`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#PropertyNameMapping) explicit name mapping instead field tags.\n* [`ProcessWithoutTags`](https://pkg.go.dev/github.com/swaggest/jsonschema-go#ProcessWithoutTags) enables processing fields without any tags specified.\n\n### Virtual structure\n\nSometimes it is impossible to define a static Go `struct`, for example when fields are only known at runtime.\nYet, you may need to include such fields in JSON schema reflection pipeline.\n\nFor any reflected value, standalone or nested, you can define a virtual structure that would be treated as a native Go struct.\n\n```go\ns := jsonschema.Struct{}\ns.SetTitle(\"Test title\")\ns.SetDescription(\"Test description\")\ns.DefName = \"TestStruct\"\ns.Nullable = true\n\ns.Fields = append(s.Fields, jsonschema.Field{\n    Name:  \"Foo\",\n    Value: \"abc\",\n    Tag:   `json:\"foo\" minLength:\"3\"`,\n})\n\nr := jsonschema.Reflector{}\nschema, _ := r.Reflect(s)\nj, _ := assertjson.MarshalIndentCompact(schema, \"\", \" \", 80)\n\nfmt.Println(\"Standalone:\", string(j))\n\ntype MyStruct struct {\n    jsonschema.Struct // Can be embedded.\n\n    Bar int `json:\"bar\"`\n\n    Nested jsonschema.Struct `json:\"nested\"` // Can be nested.\n}\n\nms := MyStruct{}\nms.Nested = s\nms.Struct = s\n\nschema, _ = r.Reflect(ms)\nj, _ = assertjson.MarshalIndentCompact(schema, \"\", \" \", 80)\n\nfmt.Println(\"Nested:\", string(j))\n\n// Output:\n// Standalone: {\n//  \"title\":\"Test title\",\"description\":\"Test description\",\n//  \"properties\":{\"foo\":{\"minLength\":3,\"type\":\"string\"}},\"type\":\"object\"\n// }\n// Nested: {\n//  \"definitions\":{\n//   \"TestStruct\":{\n//    \"title\":\"Test title\",\"description\":\"Test description\",\n//    \"properties\":{\"foo\":{\"minLength\":3,\"type\":\"string\"}},\"type\":\"object\"\n//   }\n//  },\n//  \"properties\":{\n//   \"bar\":{\"type\":\"integer\"},\"foo\":{\"minLength\":3,\"type\":\"string\"},\n//   \"nested\":{\"$ref\":\"#/definitions/TestStruct\"}\n//  },\n//  \"type\":\"object\"\n// }\n```\n\n### Custom Tags For Schema Definitions\n\nIf you're using additional libraries for validation, like for example \n[`go-playground/validator`](https://github.com/go-playground/validator), you may want to infer validation rules into \ndocumented JSON schema.\n\n```go\ntype My struct {\n    Foo *string `json:\"foo\" validate:\"required\"`\n}\n```\n\nNormally, `validate:\"required\"` is not recognized, and you'd need to add `required:\"true\"` to have the rule exported to \nJSON schema.\n\nHowever, it is possible to extend reflection with custom processing with `InterceptProp` option.\n\n```go\ns, err := r.Reflect(My{}, jsonschema.InterceptProp(func(params jsonschema.InterceptPropParams) error {\n    if !params.Processed {\n        return nil\n    }\n\n    if v, ok := params.Field.Tag.Lookup(\"validate\"); ok {\n        if strings.Contains(v, \"required\") {\n            params.ParentSchema.Required = append(params.ParentSchema.Required, params.Name)\n        }\n    }\n\n    return nil\n}))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggest%2Fjsonschema-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswaggest%2Fjsonschema-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggest%2Fjsonschema-go/lists"}