Json-Import of nodes with taxonomy terms I'm running Drupal 8.3.6 and I try to import a json stream originating from typo3. It is essentially a list of blog posts in this format:

[{
    "id": "1",
    "title": "Title",
    "bodytext": "Bodytext with html Mark-Up",
    "datetime": "1269437640",
    "keywords": "term1, term2, term3, term4,..."
},{
    "id": "2",
    "title": "Title 2",
    "bodytext": "Another Bodytext with html Mark-Up",
    "keywords": "term6, term3, term9, term7,..."
}]


I came up with a small module following these instructions, which works well for the title and bodytext: 

protected function createBlog(string $json) {
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {

      $node = Node::create(array(
        'type' =&gt; 'blog',
        'langcode' =&gt; 'de',
        'uid' =&gt; '1',
        'status' =&gt; 1,
        'title' =&gt; $blog['title'],
        'body' =&gt; ['value' =&gt; $blog['bodytext'], 'format' =&gt; 'full_html'],
      ));

      $node-&gt;save();
    }
  }


However I'm struggling to get the terms created and referenced by the nodes. I tried something like this, but it doesn't work:

protected function createBlog(string $json) {
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {
      foreach ($blog['keywords'] as $tag) { // Loop through each blog entries keywords and create terms
        $term = Term::create(array(
          'name' =&gt; $tag,
          'vid' =&gt; 'tags',
        ))-&gt;save();
      }

      $node = Node::create(array(
        'type' =&gt; 'blog',
        'langcode' =&gt; 'de',
        'uid' =&gt; '1',
        'status' =&gt; 1,
        'title' =&gt; $blog['title'],
        'field_tags' =&gt; $blog['keywords'], // I would need to have the terms from above in an array to add them here, right?
        'body' =&gt; ['value' =&gt; $blog['bodytext'], 'format' =&gt; 'full_html'],
      ));

      $node-&gt;save();
    }
  }


The terms do not get created and if they would, I wouldn't know how to associate them with the nodes. Also if it would work, there would be the problem that on creation of the terms I do not check if a term already exists. This would be necessary because nodes can have the same terms.

Is it possible to achieve this with my approach? If yes, can you tell me how? I also looked in to migrate_plus but I find it quite complicated. 

Any help would be appreciated! 

Andi
Not knowing how the rest of your dependencies are set up, one thing I notice off the bat is that your keywords source field is a comma-separated single string, but you're treating it as an array of values in your processor. Maybe something like this:

protected function createBlog(string $json)
{
    $jsonout = json_decode($json, TRUE);

    foreach ($jsonout as $blog) {
        $newTags = explode(', ', $blog['keywords']);
        $newTagIDs = [];
        foreach ($newTags as $tag) {
            $newTagIDs[] = Term::create(array(
                'name' =&gt; $tag,
                'vid' =&gt; 'tags'
            ))-&gt;save();
        }

        $node = Node::create(array(
            'type' =&gt; 'blog',
            'langcode' =&gt; 'de',
            'uid' =&gt; '1',
            'status' =&gt; 1,
            'title' =&gt; $blog['title'],
            'field_tags' =&gt; $newTagIDs,
            'body' =&gt; ['value' =&gt; $blog['bodytext'], 'format' =&gt; 'full_html']
        ));

        $node-&gt;save();
    }
}


You're right that your approach would create multiple copies of the same term, though. The Entity Lookup plugin from the migrate_plus module might provide some help:

// $this-&gt;entityManager is a dependency-injected instance of Drupal\Core\Entity\EntityManagerInterface
$query = $this-&gt;entityManager-&gt;getStorage('taxonomy_term')
    -&gt;getQuery()
    -&gt;condition('name', $termNameToLookup)
    -&gt;condition('vid', $vocabularyToLookup);
$results = $query-&gt;execute();
if (empty($results)) {
    // term doesn't exist in that vocabulary; should add it
} else {
    // the term already exists in that vocabulary; do something with it
}