Skip to content

Deterministically generating a string from object #15628

@kevinburke

Description

@kevinburke

There are a few different contexts where it can be useful to generate a string representation of an object. The basic idea is that the same in-memory representation of the object should always yield the same string.

  • You may want to use an object as a cache key.
  • You may want to generate a MAC for an object, for example for use with JSON Web Tokens.
  • You may want to store an object to disk or to the database in a way that it can be re-created in memory later.

For each of these use cases, a serialization function should generate the same string, or Buffer, for the same object. Generating different strings could lead you to incorrectly conclude the object changed.

The most common serialization technique - used for example by the node-jsonwebtoken is to call JSON.stringify. However, JSON.stringify does not guarantee deterministic output. The latest ECMA spec for JSON.stringify says that it should produce the same order as Object.keys, which should produce the same order as for ... in, which uses Object.[Enumerate] to enumerate object keys. [[Enumerate]] is a) deprecated, and b) the specification contains this note:

The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.

It would be nice if there were any function in the standard library that could convert an object to a string in a deterministic way. This could be solved in any of the following ways:

  • Declaring that Node's JSON.stringify will always produce the same string output for the same object input. JSON.stringify is controlled by an ECMA specification, and V8, so I'm not sure that this is feasible.

  • Adding a new API to either crypto or util that takes an Object as input and generates a string, guaranteeing it will generate the same output across Node versions.

  • Documenting that some existing API, for example, Buffer.from(object), util.format(fmt, object) with some format string, will always generate the same string for the same object (and different strings for different objects).

I guess there is some question of what "the same" means - roughly, I would think two objects that are equal as defined by something like Lodash's isEqual function should generate the same string, and objects that fail an isEqual check should generate different strings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues that request new features to be added to Node.js.questionIssues that look for answers.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions