In Craft 3 plugins, should CRUD operations go in Controllers or Services? The documentation states:


  Many service methods perform some sort of operation for a given model, such as a CRUD operation.


(Link)

But browsing through existing plugins, I see the CRUD logic is most often done in controllers. 

What's the best practice here?
Putting aside the term "CRUD" for a moment, it essentially breaks down like this...


If something wants to ping your site, it is (almost) inevitably going to be pinging a Controller.
If you want to do something in the database (create, update, delete), you should probably be doing that in a Service.


Which raises the question, "how/where to bridge that gap?"

The answer is, "it depends."

You could keep most of your logic in the Controller, and just move the DB interactions to the Service. Or you could immediately ping a Service method as soon as your Controller is hit. Either way is fine, and it depends heavily on what the site requires, and what you (as the developer) are more comfortable with.

As you noted, sometimes people bend the rules and put DB interactions directly into the Controller method. While that's frowned upon, there may not be any negative repercussions. So don't worry too much about how other people are handling it... just do what makes sense to you.