I'm not seeing my computed field show up in JSON:API output with computed_field 4.x.

I was previously using computed_field 2.x and the field was appearing as expected in JSON:API output.

I updated to computed_field 4.x and created a plugin following the TestString.php example in test_computed_field_plugins very closely. (My computed field outputs a string as well.) I created the field via the "Add computed field" process in the UI and attached my plugin to it.

The computed field output shows up properly when the node is rendered in the site theme, but not when viewing the JSON:API output for the node. The field is not listed there at all.

I also tried modeling my plugin after the version of TestString.php that's in test_computed_field_output, (though I'm not sure I got the attach exactly right), but still nothing in JSON:API output.

Should the field just work? Is there something more I need to do to get it to show up?

Thanks in advance.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jeffschuler created an issue. See original summary.

jeffschuler’s picture

I tried enabling the test_computed_field_output module and creating a computed field with each of its plugins. Same problem: they show up in the theme but not in JSON:API output.

jeffschuler’s picture

Thanks @joachim. It does just work in 2.x & 3.x. Both those links you shared would be pre 4.x, no?

I downgraded back to 3.x to keep moving, but will revisit and dig further when time allows.

I could see the field listed in JSON:API Extras' Resource overrides pane for my entity (/admin/config/services/jsonapi/resource_types)... so it's being registered in some way.

joachim’s picture

> Thanks @joachim. It does just work in 2.x & 3.x. Both those links you shared would be pre 4.x, no?

They are for computed fields in general, independent of this module.

daniel korte’s picture

I’m experiencing the same issue. The field shows up everywhere except the JSON output.

daniel korte’s picture

Okay, it worked for me if I defined my computed field in code only (i.e. not adding the computed field to an entity bundle via the Field UI):

/**
 * Computed field string.
 *
 * @ComputedField(
 *   id = "computed_field_attached",
 *   label = @Translation("Computed field"),
 *   field_type = "string",
 *   no_ui = TRUE,
 *   attach = {
 *     "scope" = "base",
 *     "field_name" = "computed_field",
 *     "entity_types" = {
 *       "node" = {
 *         "article",
 *       },
 *     },
 *   },
 * )
 */
joachim’s picture

In that case, it it looks like this is a base field / bundle field problem.

lambic’s picture

I'm seeing the field in my jsonapi output, but it's only showing the first value. My computeValue method returns [1,2] but in the jsonapi I just see "1"

spurlos’s picture

StatusFileSize
new2.53 KB

The root cause here comes from how JSON:API filters out internal properties.

By default, \Drupal\jsonapi\JsonApiResource\ResourceObject::extractContentEntityFields() calls \Drupal\Core\TypedData\TypedDataInternalPropertiesHelper::getNonInternalProperties(), which relies on \Drupal\Core\Field\FieldConfigBase::isInternal() to determine whether a field should be exposed.

That method checks the field definition for the internal key. If it’s missing, it falls back to isComputed(). This means any computed field without an explicit definition is treated as internal and therefore excluded from the JSON:API output.

Since \Drupal\computed_field\Entity\ComputedField does not provide a definition, it always ends up flagged as internal purely because it’s computed.

To work around this, I patched ComputedField so that it returns a definition from ::getFieldStorageDefinition(), and I propagate the internal flag from the plugin definition.

  • By default, internal = FALSE, because most field properties are intentionally public.
  • Developers can still override this via the plugin config (or extend the plugin settings form) if they want to explicitly hide a computed field from JSON:API.

This approach ensures that computed fields are no longer discarded automatically, while still respecting Drupal’s intent around the internal flag.

joachim’s picture

Version: 4.0.0-alpha2 » 4.0.x-dev
Category: Support request » Bug report
Status: Active » Needs work

Good find!!

So do all computed fields from this module show in JSONAPI with this patch?

What's the magic getting needed for?

And also, could you make this a MR please?

spurlos’s picture

StatusFileSize
new2.5 KB

Small adjustment to previous patch. Removed parent::_get() in ComutedField.php as it does not exists in FieldConfigBase

I'll create a MR when i'll have time.

redndahead made their first commit to this issue’s fork.

redndahead’s picture

Status: Needs work » Needs review

This is my first MR so let me know if I need to do something different.

joachim’s picture

Status: Needs review » Needs work

Yeah, you've put your commits and the MR on the wrong branch.

Leave 4.0.x as is.

Put your commits on the feature branch which you've created -- computed_field-3353839/3353839-show-computed-field

joachim’s picture

Issue tags: +Needs tests

Also, a kernel test would be nice!

redndahead’s picture

Hopefully I've done the MR correctly this time.

I don't think I'm the right one to write the test. I don't use this feature and I provided the MR as a low hanging fruit for me to learn how to create MR's and I believe if I post an issue I should at least try to help out in another issue.

rishvi’s picture

I tried to address the review feedback on MR !22 locally.
I’ll push the update to the issue fork if access is available, or open a follow-up MR if needed.

joachim’s picture

This needs a test before it goes anywhere -- I'm frankly a bit confused by the interplay between plugin / config entity / field definitions.

rishvi’s picture

StatusFileSize
new3.21 KB
genellann’s picture

StatusFileSize
new3.77 KB

I tried #22 and my computed fields still didn't show up in JSON:API.

The problem is that JSON:API asks the field definition whether the field is internal. The field definition never asks the plugin, it just uses the core default, and the core default hides all computed fields. So the new flag from #22 never gets checked.

I rerolled #22 and added an isInternal method to the field definition so it asks the plugin. Now computed fields created in the UI show up in JSON:API.

Tested on Drupal 11.3 with 4.0.0.

meeni_dhobale’s picture

StatusFileSize
new4.54 KB

Tested the patch from #23 (3353839-23.patch) on Drupal 11.x, PHP 8.3. Without it, isInternal() always returns TRUE because the field definition never asks the plugin — so JSON:API strips every computed field no matter what the plugin actually wants. With it applied, isInternal() follows the plugin's internal attribute like it should, and the field shows up in JSON:API.

@joachim asked for tests above, so here's one: 3353839-24.patch adds a ComputedFieldInternalKernelTest covering both cases — a plugin that doesn't mark itself internal, and one that does. Checked it fails without #23's patch and passes with it.

One more thing: MR !22's branch has actually regressed since this was last tested. The "Remove fallback value" commit deleted ComputedField::isInternal() entirely instead of just trimming it, so it's back to the same bug. It still needs at least return $this->getFieldValuePlugin()->isInternal();.