MCPcopy Index your code
hub / github.com/Kangaroux/go-map-schema

github.com/Kangaroux/go-map-schema @v0.6.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.6.1 ↗ · + Follow
63 symbols 108 edges 7 files 48 documented · 76% updated 5y agov0.6.1 · 2021-06-07★ 853 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

go-map-schema

Go Reference GitHub tag (latest SemVer)

Table of Contents

Overview

go-map-schema is a tiny library that's useful for comparing a map (usually from JSON) to a struct, and finding any fields that are missing or that have incompatible types.

Use Case

The most common usage would be for an API that accepts JSON from clients.

Before we can fulfill the request we need to know if the JSON matches what we expect. By verifying the JSON before we even try to json.Unmarshal it into a struct, we can be sure the JSON will be safely converted with no loss of data or swallowed errors.

As a result, you end up with an API that has

  1. strict type checking, and
  2. can give the client helpful error messages when the request is invalid

Do I Really Need This?

For something like an API, it's worth asking who is going to be the client that is using the API. Is this an API for your single page app, or are you providing a service and it will be used by other developers?

If the API is "internal" and only used within the context of your site, I don't think it's necessary. But if someone is trying to use your API, I think it's worth having. API documentation is rarely perfect, and giving the client a readable error can help them debug when a request throws a 400 Bad Request.

Examples

Read below for a quick look at how you can use go-map-schema.

For more examples, check out the examples/ directory.

Usage

Suppose we have a Person model that contains a nested Address

type Address struct {
    Country     string `json:"country"`
    City        string `json:"city"`
    AddressLine string `json:"address_line"`
}

type Person struct {
    FirstName string  `json:"first_name"`
    LastName  string  `json:"last_name"`
    Age       int     `json:"age"`
    Address   Address `json:"address"`
}

and a client comes along and makes a POST request with this JSON.

{
    "first_name": "Jessie",
    "age": "26",
    "address": {
      "country": "US",
      "city": null
    }
}

We can unmarshal the JSON into a map to make it easier to work with, and then compare it with the Person model.

src := make(map[string]interface{})
json.Unmarshal(payload, &src)

dst := Person{}
results, err := schema.CompareMapToStruct(&dst, src)

After comparing we now have a CompareResults instance stored in results.

type CompareResults struct {
    MismatchedFields []FieldMismatch
    MissingFields    []FieldMissing
}

With this, we can quickly see which fields have mismatched types, as well as any fields that are in the Person struct but not the JSON.

Check out examples/type-errors for the complete example.

Universal Type Names

By default, CompareMapToStruct will use the DetailedTypeName func when reporting a type mismatch. The detailed type name includes some extra information that you may not want a client to see.

For example, trying to convert a float64 into an int32 will report a mismatch between float64 and int32.

If you don't want to include bit size, you can use SimpleTypeName which converts floatX -> float, intX -> int, uintX -> uint.

opts := &schema.CompareOpts{
    TypeNameFunc: schema.SimpleTypeName,
}

schema.CompareMapToStruct(dst, src, opts)

Extension points exported contracts — how you extend this code

ConvertibleFunc (FuncType)
ConvertibleFunc takes a dst type (t) and a src value (v) and returns true if v is convertible to t.
schema.go
TypeNameFunc (FuncType)
TypeNameFunc takes a reflection type and returns its name as a string.
schema.go

Core symbols most depended-on inside this repo

Errors
called by 4
schema.go
TypeNameWithArticle
called by 4
lang.go
String
called by 3
schema.go
compare
called by 2
schema.go
isIntegerType
called by 2
schema.go
FieldNameWithPath
called by 2
lang.go
Message
called by 1
schema.go
MessageWithField
called by 1
schema.go

Shape

Function 36
Struct 15
Method 7
TypeAlias 3
FuncType 2

Languages

Go100%

Modules by API surface

schema_test.go25 symbols
schema.go19 symbols
lang.go5 symbols
lang_test.go4 symbols
examples/type-errors/main.go4 symbols
examples/required-fields/main.go3 symbols
error.go3 symbols

For agents

$ claude mcp add go-map-schema \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page