Menu items in WordPress are just posts, but before you can update a nav menu item, you need to do some translation of the Post object into something that wp_update_nav_menu_item will understand.
Below is a function that will take a menu item as an array (e.g. as it is returned from the REST API) and convert the array keys to something that’s ready for wp_update_nav_menu_item() to act on:
public function prepareMenuItemForUpdate($menu_item_data = []) {
/* Classes can't be an array, convert it to a string */
$classes = is_array($menu_item_data['classes']) ? join(' ', $menu_item_data['classes']) : $menu_item_data['classes'];
$ret = array(
'menu-item-db-id' => $menu_item_data['ID'],
'menu-item-object-id' => $menu_item_data['object_id'],
'menu-item-object' => $menu_item_data['object'],
'menu-item-parent-id' => $menu_item_data['menu_item_parent'],
'menu-item-position' => $menu_item_data['menu_order'],
'menu-item-type' => $menu_item_data['type'],
'menu-item-title' => $menu_item_data['title'],
'menu-item-url' => $menu_item_data['url'],
'menu-item-description' => $menu_item_data['description'],
'menu-item-attr-title' => $menu_item_data['attr_title'],
'menu-item-target' => $menu_item_data['target'],
'menu-item-classes' => $classes,
'menu-item-xfn' => $menu_item_data['xfn'],
'menu-item-status' => $menu_item_data['post_status'],
'menu-item-post-date' => $menu_item_data['post_date'],
'menu-item-post-date-gmt' => $menu_item_data['post_date_gmt'],
);
if ($ret['menu-item-description'] == null) {
$ret['menu-item-description'] = " "; //This needs a blank space if unset
}
if ($ret['menu-item-attr-title'] === null) {
$ret['menu-item-attr-title'] = "";
}
return $ret;
}
}