It takes a bit of getting used to, but once you get the hang of it you can create very complex json directly in your select statement. I've been using it quite a bit lately and it saves me from building the json with JSONGenerator. I usually add the select statement with one column called "json_data" to a datawindow and use the datawindow to retrieve it.
JSONGenerator is still useful, so it depends on your use case. In other code I've created some parts of my json with "FOR JSON" and some parts with JSONGenerator and pieced them together with JSONPackage.
The datawindow control also has an ExportJSON function (which I haven't used) to export the contents of the datawindow columns to a json string.
So, there are a heap of ways to do it, it probably depends on exactly what the json looks like that you are trying to create.