We are already long time since the 4.4 release in which that end point was introduced, and while it is far from being perfect it is probably almost always better to use it instead of the admin-ajax end point.

So the question is, should we treat the usage of admin-ajax as a "doing it wrong" thing, same way as query_posts is treated?

"probably almost always better to use it" I'd like to see some backing for this claim.
– RarstOct 27 '17 at 6:19

@rarst, It does not run as admin which means less initialization for things which are pointless in front end context., and at least theoretically can be cached by external caching services like cloudflare, something that is harder to do on admin-ajax, but maybe I am wrong here
– Mark KaplunOct 27 '17 at 6:35

3 Answers
3

You can write your own, maybe high-performance, end point for "classical" AJAX requests as well, which is something not really explored and documented anywhere. I doubt that it is the better way, so I would suggest to just let things live that are not yet officially deprecated.

Aside from that, pretty much everything that is suggested by the "official" development side of things, is either proven to be "not the best" on this very side or in GitHub repositories all over the place.

My (slightly personal) opinion on this topic: Let things live aside of each other. We have that many and that different and diverse communities in "our" nano-cosmos named WordPress, so we might be able to accept that legacy stuff has its place as well as new and maybe not-that-bad ideas like the REST API.

The standard AJAX API is still the way to deal with AJAX requests. I don't see any reason to construct a consensus about its deprecation.

It does the most used basic privilege check (doesn't run "as admin" as you said in a comment).

It is reliable, because it will most likely not be disabled – something that can easily happen with the REST API.

It isn't significantly slower than the REST API.

There are already thousands of working code examples that you just can use in your own project.

If you have a private project, meaning your code is not distributed as a plugin or theme to unknown environments, then feel free whatever you want. :) In most other cases, the AJAX API is probably still the way to go.

And no matter what your personal opinion is, refrain from downvotes on answers that are technically valid and without bad side effects like query_posts() but using a different approach than you do.

actually it is as easy to disable the admin-ajax as it is the rest api, in both cases you will need to have an htaccess rule for it.
– Mark KaplunOct 27 '17 at 8:21

and I didn't mean that it runs as admin, but that it loads admin context :(, lets not take things out of obvious context
– Mark KaplunOct 27 '17 at 8:23

@MarkKaplun .htaccess–rules… only if you are using Apache.
– kaiserOct 27 '17 at 10:27

@kaiser, ok, let me rephrase, you can not block the wp-json end point in php, same as the admin-ajax one
– Mark KaplunOct 27 '17 at 13:44

1

@mark-kaplun REST can be disabled completely with 1 line of code no need for htaccess. Just remove this action github.com/WordPress/WordPress/blob/master/wp-includes/… and REST API does not work anymore. To prevent AJAX actions from code you need to know the exact name of the action. So breaking REST without access to the system is easier than breaking AJAX, by far.
– gmazzap♦Oct 27 '17 at 16:52

Moreover, REST to work needs to perform regex for rewrite rules. Both frontend rewrite rules and REST rewrite rules regexes are executed in a REST request. In a system with a lot of rules (and if you replace AJAX with REST you might have hundreds) this could be very slow, regex perfroming is a slow operation. So assuming REST is faster might not be a good bet.
– gmazzap♦Oct 27 '17 at 16:53

Finally, you can recognize an AJAX request pretty early, because DOING_AJAX is defined very early. It means that you selectively disable plugins, themes, remove hooks and other performance enhancements. With REST you need to wait for parse_request to know when you are inside a REST request, and at that point all plugins and themes were already loaded.
– gmazzap♦Oct 27 '17 at 16:59

@gmazzap, yes and it can also be done by removing the end point from routing. I don't want to even try to dig into admin-ajax to see if same can be done there. The real life facts are that core is moving to use it in all new code, and therefor it will be enabled for all. This is really irrelevant to my question, wp-json is the future, admin-ajax is the hacked past. I can understand people disagreeing with what I suggest but I do not get this discussion about how easy it is to disable them, both are easy if you know what you are doing
– Mark KaplunOct 27 '17 at 17:13

@mark-kaplun In that blog they tested with a single REST endpoint (LOL) and possibly 10 frontend rules. Run same tests with 500 REST endpoints and 100 frontend rules... Plus, as I said, AJAX can be optimized, REST can't. I can disable all plugins for AJAX requests, for example. In a system with a lot of heavy plugins, if I ran AJAX without them and REST with them, what will be faster? The only system performance tests that matter are those you run in your system, and every system is different. Assuming REST is always faster is wrong, that's my point.
– gmazzap♦Oct 27 '17 at 17:43

Feb 12 '18 : After testing what I learn thanks to Nathan Johnson, I agreed again with the conclusion "Let things live aside of each other".

original answer of the Jan 31 '18

Since 3 mounths (since I read all answers here), I agreed the neutral conclusion of "Let things live aside of each other" and I decided to try to use REST API in new projects in cases where I used AJAX before.

But today I found a technical difference : admin-ajax.php use the build-in authentication system of WordPress to know the current connected user and REST API need a code addition to manage authentication.

Then I think that REST API cannot completly replace AJAX system now and it's easier to use admin-ajax.php rather than REST on AJAX calls in backend or frontend. And REST API will be used for access beetween different servers.