Skip to content

Docs: inconsistent builder API, unverified mapToClass, and stale README feature list #63

Description

@DannyvdSluijs

Documentation drift between jsonmapper.net, the README, and the released package

Summary

The published documentation exists in three places — the site at jsonmapper.net, the repository README (which Packagist renders), and the released package itself — and they disagree with each other in several places. The drift runs in both directions: the README is behind the site on features, and the site's Introduction page appears to be ahead of the latest release on API.

The practical consequence: a new user's first copy-paste fails, and an evaluating maintainer cannot tell from the published material which entry point is the supported one. This came up while evaluating the package as a dependency, where "which API do I pin against?" was the blocking question and could not be answered from the docs.

Baseline for everything below: latest release 2.25.1 (2025-05-26), php: ^7.4 || ^8.0.

Verification status: every item below is verified against published material only — the site, the README as rendered on Packagist, and the Packagist manifest. Items marked ⚠️ additionally need checking against the source of 2.25.1 before the fix direction is decided, because the correct resolution depends on what the code actually does.


Findings

1. ⚠️ The two builder examples use different constructors

The Introduction page creates the builder with a static new(). The Setup page creates it with a static create().

At most one of these is correct. Whichever it is, the other page is broken for anyone following it.

Fix: confirm the real static constructor, correct the other page, and — if both exist — say so explicitly and pick one for all examples.


2. ⚠️ mapToClass() appears in exactly one place and nowhere else

The Introduction page's headline example maps a JSON string to a class name, returning a new instance. That method does not appear on the Setup page, does not appear in the README, and does not appear in any other documentation page.

The README's equivalent example uses the factory and maps a decoded object onto a pre-constructed instance instead.

These are materially different APIs — one takes a class-string and constructs for you, the other requires you to construct first. A reader cannot tell which is supported.

This is the highest-impact item. It sits in the first code block a new user sees, and for anyone evaluating the library it determines whether the package fits their design.

Fix: confirm whether mapToClass() exists in 2.25.1.

  • If it does: document it on the Setup page alongside the factory and README forms, and add it to the README.
  • If it is develop-only: remove it from the Introduction until it ships, or mark it clearly as unreleased.

3. ⚠️ The two examples use different namespaces for the same fixture class

The Introduction page and the README both illustrate with a SimpleObject, but under different namespace roots — one nests the test namespace inside the package namespace, the other reverses it.

At most one matches the actual test fixtures.

Secondary point worth considering: neither should really appear in user-facing documentation at all. Both examples point a new user at a class that lives in the test suite and does not exist in their application. A neutral example namespace would serve better.


4. Typo: withProperyMapper

The Setup page's builder example calls a method spelled withProperyMapper — missing the t in "Property".

Two possibilities, and they need different fixes:

  • The documentation has a typo → correct the page.
  • The method itself is misspelled in the API → then this is a public API defect, not a docs one, and needs a correctly-spelled alias plus a deprecation. Worth raising separately if so.

5. The same builder example sets the property mapper twice

That example calls the misspelled variant with a directly constructed property mapper, and then also calls a correctly-spelled variant with the built one. Both in the same chain.

Either one call is redundant, or the two methods do different things and the difference is undocumented. As written, a reader cannot tell which call wins.


6. Example snippets are not copy-pasteable

Several classes in the Setup examples are referenced by short name with no use statements and no fully-qualified names — the property mapper, the scalar caster, the cache implementation, the builders themselves.

The factory example on the same page does use fully-qualified names, so the page is internally inconsistent about this too.

Fix: pick one convention — FQCNs, or a use block at the top of each snippet — and apply it site-wide.


7. The README's feature list is stale

The README lists: case conversion, debugging, docblock annotations, final callback, namespace resolving, and typed properties.

The site documents those plus constructor support, rename, value transformation, PHP attributes, and Laravel Eloquent — and the Introduction page additionally claims enum support on PHP 8.1+ and readonly properties and classes.

Since Packagist renders the README, the package's most-visited page understates the feature set by roughly half. For anyone comparing mappers, several of those omitted items are exactly the differentiators.


8. No "available since" convention

The Setup page does this well in one place — it notes the versions in which the builder and the property-mapper builder were introduced. Nowhere else on the site does it.

Given that the site appears to track a development branch while the released package lags, a consistent version annotation on every non-original API would remove most of the ambiguity that produced this report.

Fix suggestion: an "available since x.y.z" line on every middleware and builder page, plus a site-wide banner stating which version the documentation targets.


Suggested resolution order

  1. Resolve item 2 — confirm mapToClass against the source of the latest release. Everything else is cosmetic by comparison.
  2. Resolve item 1 — confirm the builder's static constructor.
  3. Fix items 4, 5, 6 — small, mechanical, safe to hand to a first-time contributor.
  4. Fix item 3 — pick a neutral example namespace and apply it to both the site and the README.
  5. Fix item 7 — regenerate the README feature list from the site's middleware index.
  6. Adopt item 8 as a documentation convention so this class of drift is self-correcting.

Suggested preventative measures

  • Test the examples. Extract the documentation snippets into an executable examples suite that runs in CI against the released package. This is the only measure that makes items 1, 2, 4, and 6 impossible to reintroduce.
  • Single source for the feature list. Generate the README's list from the same data as the site's middleware index rather than maintaining both by hand.
  • State the target version. A banner on the site declaring which release the docs describe, and a visible marker on anything documented ahead of a release.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationgood first issueGood for newcomers

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions