CINXE.COM
IPLD ♦ Data Model Kinds
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/css/layout.css?1732633144785"> <link rel="stylesheet" href="/css/nav.css?1732633144785"> <link rel="stylesheet" href="/css/style.css?1732633144785"> <link rel="stylesheet" href="/css/prismjs@1.24-themes-prism.css"> <title>IPLD ♦ Data Model Kinds</title> </head> <body> <header> <div class="sidebar-button" onclick="document.getElementById('sidebar').classList.toggle('sidebar-open')"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"> <path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path> </svg> </div> <a href="/" class="logo">IPLD</a> <aside id=breadcrumbs> <ul> <li><a href="/docs">docs</a></li> <li><a href="/docs/data-model">data-model</a></li> <li><a href="/docs/data-model/kinds/">kinds</a></li> </ul> </aside> </header> <aside id=sidebar> <nav> <ul> <li> <a href="/docs/">Docs</a><ul> <li> <a href="/docs/intro/">Intro</a><ul> <li> <a href="/docs/intro/hello-world/">Hello, World</a></li> <li> <a href="/docs/intro/primer/">The Brief Primer</a></li> <li> <a href="/docs/intro/ecosystem/">InterPlanetary Ecosystem Overview</a></li> <li> <a href="/docs/intro/community/">Finding Community</a></li></ul></li> <li> <a href="/docs/motivation/">Motivation</a><ul> <li> <a href="/docs/motivation/benefits-of-content-addressing/">Benefits of Content Addressing</a></li> <li> <a href="/docs/motivation/data-to-data-structures/">From Data to Data Structures</a></li></ul></li> <li> <a href="/docs/codecs/">Codecs</a><ul> <li> <a href="/docs/codecs/known/">Known Codecs</a><ul> <li> <a href="/docs/codecs/known/dag-cbor/">DAG-CBOR</a></li> <li> <a href="/docs/codecs/known/dag-json/">DAG-JSON</a></li> <li> <a href="/docs/codecs/known/dag-pb/">DAG-PB</a></li></ul></li></ul></li> <li> <a href="/docs/data-model/">Data Model</a><ul> <li> <a href="/docs/data-model/node/">Nodes</a></li> <li class="active-page"> <a href="/docs/data-model/kinds/">Kinds</a></li> <li> <a href="/docs/data-model/pathing/">Pathing</a></li> <li> <a href="/docs/data-model/traversal/">Traversal</a></li></ul></li> <li> <a href="/docs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/docs/advanced-data-layouts/intro/">Intro to ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/naming/">ADL Naming</a></li> <li> <a href="/docs/advanced-data-layouts/signalling/">Signalling ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/dynamic-loading/">Dynamic Loading</a></li> <li> <a href="/docs/advanced-data-layouts/known/">Known ADLs</a></li></ul></li> <li> <a href="/docs/schemas/">Schemas</a><ul> <li> <a href="/docs/schemas/intro/">Introduction</a><ul> <li> <a href="/docs/schemas/intro/compare/">compare</a></li> <li> <a href="/docs/schemas/intro/goals/">Goals</a></li> <li> <a href="/docs/schemas/intro/feature-summary/">Feature Summary</a></li></ul></li> <li> <a href="/docs/schemas/features/">Features</a><ul> <li> <a href="/docs/schemas/features/typekinds/">Type Kinds</a></li> <li> <a href="/docs/schemas/features/representation-strategies/">Representation Strategies</a></li> <li> <a href="/docs/schemas/features/links/">Links</a></li> <li> <a href="/docs/schemas/features/indicating-adls/">Using ADLs in Schemas</a></li></ul></li> <li> <a href="/docs/schemas/using/">Using Wisely</a><ul> <li> <a href="/docs/schemas/using/authoring-guide/">Authoring Guide</a></li> <li> <a href="/docs/schemas/using/migrations/">Migrations</a></li></ul></li></ul></li> <li> <a href="/docs/synthesis/">Synthesis</a><ul> <li> <a href="/docs/synthesis/gtd/">Getting Things Done</a></li> <li> <a href="/docs/synthesis/building-in-alignment/">Building in Alignment</a></li> <li> <a href="/docs/synthesis/how-ipfs-web-gateways-work/">How IPFS Web Gateways Work</a></li> <li> <a href="/docs/synthesis/encryption/">Working With Encryption</a></li></ul></li></ul></li> <li> <a href="/specs/">Specs</a><ul> <li> <a href="/specs/about/">About the Specifications</a></li> <li> <a href="/specs/codecs/">Codecs</a><ul> <li> <a href="/specs/codecs/dag-cbor/">DAG-CBOR</a><ul> <li> <a href="/specs/codecs/dag-cbor/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-cbor/fixtures/">DAG-CBOR Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-cbor/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li> <li> <a href="/specs/codecs/dag-cosmos/">DAG-COSMOS</a><ul> <li> <a href="/specs/codecs/dag-cosmos/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-cosmos/cosmos_state/">cosmos_state</a></li> <li> <a href="/specs/codecs/dag-cosmos/crypto_types/">crypto_types</a></li> <li> <a href="/specs/codecs/dag-cosmos/tendermint_chain/">tendermint_chain</a></li> <li> <a href="/specs/codecs/dag-cosmos/typed_protobuf/">typed_protobuf</a></li></ul></li> <li> <a href="/specs/codecs/dag-eth/">DAG-ETH</a><ul> <li> <a href="/specs/codecs/dag-eth/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-eth/chain/">chain</a></li> <li> <a href="/specs/codecs/dag-eth/convenience_types/">convenience_types</a></li> <li> <a href="/specs/codecs/dag-eth/state/">state</a></li></ul></li> <li> <a href="/specs/codecs/dag-jose/">DAG-JOSE</a><ul> <li> <a href="/specs/codecs/dag-jose/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-jose/fixtures/">fixtures</a></li></ul></li> <li> <a href="/specs/codecs/dag-json/">DAG-JSON</a><ul> <li> <a href="/specs/codecs/dag-json/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-json/fixtures/">DAG-JSON Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-json/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li> <li> <a href="/specs/codecs/dag-pb/">DAG-PB</a><ul> <li> <a href="/specs/codecs/dag-pb/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-pb/fixtures/">DAG-PB Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-pb/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/">FBL ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/spec/">spec</a></li></ul></li> <li> <a href="/specs/advanced-data-layouts/hamt/">HAMT ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/spec/">spec</a></li> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/">HashMap (HAMT) Test Fixtures</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/alice-words/">alice-words</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/schemas/">Schemas</a><ul> <li> <a href="/specs/schemas/prelude/">prelude</a></li></ul></li> <li> <a href="/specs/transport/">Transports</a><ul> <li> <a href="/specs/transport/car/">CAR</a><ul> <li> <a href="/specs/transport/car/carv1/">CARv1 Specification</a></li> <li> <a href="/specs/transport/car/carv2/">CARv2 Specification</a></li> <li> <a href="/specs/transport/car/fixture/">CAR Test Fixtures</a><ul> <li> <a href="/specs/transport/car/fixture/carv1-basic/">carv1-basic</a></li> <li> <a href="/specs/transport/car/fixture/carv2-basic/">carv2-basic</a></li></ul></li></ul></li> <li> <a href="/specs/transport/graphsync/">Graphsync</a><ul> <li> <a href="/specs/transport/graphsync/known_extensions/">known_extensions</a></li></ul></li> <li> <a href="/specs/transport/trustless-pathing/">Trustless Pathing</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/">Trustless Pathing Fixtures</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/unixfs_20m_variety/">unixfs_20m_variety</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/selectors/">Selectors</a><ul> <li> <a href="/specs/selectors/fixtures/">fixtures</a><ul> <li> <a href="/specs/selectors/fixtures/selector-fixtures-1/">selector-fixtures-1</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-adl/">selector-fixtures-adl</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-recursion/">selector-fixtures-recursion</a></li></ul></li></ul></li> <li> <a href="/specs/patch/">Patch</a><ul> <li> <a href="/specs/patch/fixtures/">IPLD Patch Test Fixtures</a><ul> <li> <a href="/specs/patch/fixtures/fixtures-1/">fixtures-1</a></li></ul></li></ul></li></ul></li> <li> <a href="/libraries/">Libraries</a><ul> <li> <a href="/libraries/golang/">Golang</a></li> <li> <a href="/libraries/javascript/">JavaScript</a></li> <li> <a href="/libraries/python/">Python</a></li> <li> <a href="/libraries/rust/">Rust</a></li></ul></li> <li> <a href="/design/">Design</a><ul> <li> <a href="/design/objectives/">Objectives</a></li> <li> <a href="/design/concepts/">Concepts</a><ul> <li> <a href="/design/concepts/type-theory-glossary/">type-theory-glossary</a></li></ul></li> <li> <a href="/design/libraries/">Libraries</a><ul> <li> <a href="/design/libraries/nodes-and-kinds/">nodes-and-kinds</a></li></ul></li> <li> <a href="/design/tricky-choices/">Tricky Choices</a><ul> <li> <a href="/design/tricky-choices/dag-pb-forms-impl-and-use/">dag-pb-forms-impl-and-use</a></li> <li> <a href="/design/tricky-choices/map-key-domain/">map-key-domain</a></li> <li> <a href="/design/tricky-choices/numeric-domain/">numeric-domain</a></li> <li> <a href="/design/tricky-choices/ordering/">ordering</a></li> <li> <a href="/design/tricky-choices/string-domain/">string-domain</a></li></ul></li> <li> <a href="/design/open-research/">Open Research</a><ul> <li> <a href="/design/open-research/ADL-autoexecution/">ADL autoexecution</a></li></ul></li></ul></li> <li> <a href="/tools/">Tools</a></li> <li> <a href="/glossary/">Glossary</a></li> <li> <a href="/media/">Media</a></li> <li> <a href="/FAQ/">FAQ</a></li></ul> </nav> </aside> <main> <div class=content> <h1>Kinds</h1> <p>The following is the list of essential <em>kinds</em> of data representable in the IPLD Data Model:</p> <ul> <li><a href="#null-kind">Null</a></li> <li><a href="#boolean-kind">Boolean</a></li> <li><a href="#integer-kind">Integer</a></li> <li><a href="#float-kind">Float</a></li> <li><a href="#string-kind">String</a></li> <li><a href="#bytes-kind">Bytes</a></li> <li><a href="#list-kind">List</a></li> <li><a href="#map-kind">Map</a></li> <li><a href="#link-kind">Link</a></li> </ul> <p>(Note that we use the term "<em>kinds</em>" here to disambiguate this from "<em>types</em>", which is a term we'll use at the <a href="/docs/schemas/">Schemas</a> level.)</p> <p>The <em>recursive kinds</em> are:</p> <ul> <li><a href="#list-kind">List</a></li> <li><a href="#map-kind">Map</a></li> </ul> <p>The <em>scalar kinds</em> (the complement of recursive) are:</p> <ul> <li><a href="#null-kind">Null</a></li> <li><a href="#boolean-kind">Boolean</a></li> <li><a href="#integer-kind">Integer</a></li> <li><a href="#float-kind">Float</a></li> <li><a href="#string-kind">String</a></li> <li><a href="#bytes-kind">Bytes</a></li> <li><a href="#link-kind">Link</a></li> </ul> <p>(Note that <a href="/docs/schemas/">Schemas</a> will introduce a few more kinds -- when clarification is necessary, these Data Model kinds can be called the "<em>data model kinds</em>", while the additional kinds introduced in the Schema layer are "<em>type kinds</em>".)</p> <h2 id="kinds-reference" tabindex="-1"><a class="header-anchor" href="#kinds-reference">Kinds Reference</a></h2> <h4 id="null-kind" tabindex="-1"><a class="header-anchor" href="#null-kind">Null kind</a></h4> <p>Null is a scalar kind. Its cardinality is one -- the only value is 'null'.</p> <h4 id="boolean-kind" tabindex="-1"><a class="header-anchor" href="#boolean-kind">Boolean kind</a></h4> <p>Boolean is a scalar kind. Its cardinality is two -- either the value 'true' or the value 'false'.</p> <h4 id="integer-kind" tabindex="-1"><a class="header-anchor" href="#integer-kind">Integer kind</a></h4> <p>Integer is a scalar kind and refers to whole numbers without a fractional component.</p> <p>It is important to consider codec and language limitations that may be imposed on the serialization of integers from the IPLD Data Model. For example:</p> <ul> <li>Some codecs, such as DAG-CBOR, will assume that integers must be within the 64-bit signed range and reject anything larger.</li> <li>IPLD libraries, such as go-ipld-prime, limit their in-memory representation of the integer kind to the signed 64-bit range.</li> <li>JavaScript has difficulties safely handling and representing integers outside of the 53-bit unsigned range and differentiating between integers and floats where there is no fractional component.</li> </ul> <p>See the <a href="/design/tricky-choices/numeric-domain/#integers">Integers</a> section in the "tricky design choices" pages for more details on integer domains.</p> <h4 id="float-kind" tabindex="-1"><a class="header-anchor" href="#float-kind">Float kind</a></h4> <p>Float is a scalar kind and refers to a number with a fractional component, represented with a decimal point. This may also include numbers where the fractional component is zero.</p> <p>The exact definition of float numbers in IPLD is somewhat ambiguous because the typical definitions of float numbers throughout codecs in the wild that IPLD commonly interfaces with are also somewhat ambiguous.</p> <p>In practice, we say that floats are roughly what you'd expect from IEEE 754 floats, but excluding special values such as <code>NaN</code>, <code>Infinity</code> and <code>-Infinity</code>.</p> <p>While Float is a kind in the IPLD Data Model, <strong>it is recommended that Float values be avoided when developing systems on IPLD</strong> (and content-addressable systems in general) due to:</p> <ul> <li>The broad scope for introducing variability in byte representations.</li> <li>The ambiguity introduced in some languages that may cause round-trip discrepancies; specifically JavaScript which does not clearly disambiguate between "float" and "integer" in its memory model.</li> </ul> <p>Some alternatives for representing floating point numbers include:</p> <ul> <li>Integers that are divided by a fixed number (e.g. represent cents rather than dollars and cents and divide by 100 where necessary).</li> <li>Pairs of integers representing the parts of a floating point, e.g significand & exponent.</li> <li>A byte array backed by a programmatic construct with necessary accuracy, e.g. Go's <code>big.Float</code>.</li> <li>A string form of the value with a fixed number of decimal places.</li> </ul> <p>See the <a href="/design/tricky-choices/numeric-domain/#floating-point">Floating Point</a> section in the "tricky design choices" pages for more details on float numbers and the potential ambiguities.</p> <h4 id="string-kind" tabindex="-1"><a class="header-anchor" href="#string-kind">String kind</a></h4> <p>String is a scalar kind. Its cardinality is infinite -- string sequences do not have a length limit.</p> <p>Strings are generally meant to contain "human readable" data, and are typically suggested to contain UTF-8 encoded content. However, the IPLD Data Model definition of Strings does not have any guarantees or strict requirements with regard to encoding.</p> <p>All the hazards you typically find among programming languages and libraries working with binary serialization of strings apply to strings in the IPLD data model. IPLD's data model is conceptual, it takes the world as it is, and the world of strings has widely known compatibility issues.</p> <ul> <li>Some languages/libraries guarantee a string encoding (typically UTF8), some do not.</li> <li>Some languages/libraries can handle arbitrary byte data in strings, some do not.</li> </ul> <p>While some codec specifications will define a required encoding it should be noted that in practice many codec implementations leave this kind of validation and sanitization up to the consumer (application code) and it is typical to find arbitrary byte data in strings even in codecs that explicitly forbid it.</p> <p>Applications <strong>SHOULD</strong> only encode UTF8 data into string values and use byte values when they need arbitrary bytes, but IPLD libraries may not provide these guarantees and rely on the application, or often the programming language itself, to do so instead.</p> <p>We recommend that if the library or application does check the unicode form, and wishes to do canonicalization, then the <a href="http://www.unicode.org/reports/tr15/">Unicode Normalization Form</a> should be NFC.</p> <p>Applications that only serialize valid UTF8 in string values will have fewer compatibility issues than applications that do not.</p> <p>Codec implementations that can de-serialize and roundtrip arbitrary byte data in strings will see fewer bug reports from people working with data produced by applications that serialize arbitrary byte data into strings.</p> <h4 id="bytes-kind" tabindex="-1"><a class="header-anchor" href="#bytes-kind">Bytes kind</a></h4> <p>Bytes is a scalar kind. Its cardinality is infinite -- byte sequences do not have a length limit.</p> <p>Bytes are distinct from strings in that they are not considered to have any character encoding nor generally expected to be printable as human-readable text. In order to print byte sequences as text, additional effort such as Base64 encoding may be required.</p> <p>Codecs generally treat bytes and strings differently. For example, in the DAG-JSON codec, strings will be emitted as JSON strings (and escaped as necessary), while bytes will be emitted as a form of Base64 surrounded by some indicator data.</p> <h4 id="list-kind" tabindex="-1"><a class="header-anchor" href="#list-kind">List kind</a></h4> <p>List is a recursive kind.</p> <p>Values contained in lists can be accessed by their ordinal offset in the list.</p> <h4 id="map-kind" tabindex="-1"><a class="header-anchor" href="#map-kind">Map kind</a></h4> <p>Map is a recursive kind.</p> <p>Values in maps are accessed by their "key". Maps can also be iterated over, yielding key+value pairs.</p> <h4 id="link-kind" tabindex="-1"><a class="header-anchor" href="#link-kind">Link kind</a></h4> <p>A link represents a piece of information which points to more data in another IPLD <a href="/glossary/#block">block</a>.</p> <p>Link is a scalar kind -- however, when "loaded", may become another kind, either scalar or recursive!</p> <p>Links are concretely implemented as <a href="/glossary/#cid"><code>CID</code></a>s.</p> <h2 id="implementation-references" tabindex="-1"><a class="header-anchor" href="#implementation-references">Implementation References</a></h2> <ul> <li>Kinds in Go: <a href="https://github.com/ipld/go-ipld-prime/blob/master/datamodel/kind.go">https://github.com/ipld/go-ipld-prime/blob/master/datamodel/kind.go</a></li> </ul> </div> </main> </body> </html>