Updating entities/posting data via ajax? I've got a handful of entities that need to updated on user interaction, such as:


Tracking user progress through a video, such that a listener checks playhead position every x seconds and posts information to an entity containing data on that user's progress on that video. 
A collection of checkboxes that, when clicked, automatically update the state of a corresponding value on a related entity. For the sake of argument, I don't yet know if this will be the actual entity form or a generic form/set of forms. 


In the past I attempted #1 by having a hidden, ajax-enabled form whose field values were updated every x seconds and the submit button automatically clicked, but this caused assorted ajax errors for some iOS users that were difficult/impossible to debug. Ideally I think I'd like to bypass having a form there at all. I know how to setup the js to track the data, but I'm not sure how to then pass it along to Drupal from the front-end. I'd assume I want to do something like this (via http://hayageek.com/jquery-ajax-post/), but not sure exactly how to determine the AJAX_POST_URL or how the data should be formatted.

$.ajax({
    url : "AJAX_POST_URL",
    type: "POST",
    data : formData,
    success: function(data, textStatus, jqXHR)
    {
        //data - response from server
    },
    error: function (jqXHR, textStatus, errorThrown)
    {

    }
});


For #2, I suppose it might be enough to just have a form that autosubmits via ajax when the checkbox is clicked, but given the misc errors I hit above I'm curious whether or not there might be a better way to handle it.

Happy to update this issue as needed if it's deemed too generic.
The AJAX callback URL will be a route you define in a module. The route will call a controller, which can optionally return an AjaxResponse. First define the route.

example.routing.yml:

example.ajax_callback:
  path: '/example/ajax'
  defaults:
    _controller: '\Drupal\example\Controller\AjaxController::ajaxCallback'
  requirements:
    _permission: 'some permission'


The path to set in your $.ajax() call is set above.

Then create the controller:

example/src/Controller/AjaxController.php:

namespace Drupal\example\Controller;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Controller\ControllerBase;

class AjaxController extends ControllerBase {

  public function ajaxCallback($nid, $key, $value) {
    $node = \Drupal::entityTypeManager()-&gt;getStorage('node')-&gt;load($nid);
    $node-&gt;set($key, $value);

    return new AjaxResponse(['success' =&gt; TRUE]);
  }
}