Basically, the objective is to start the X server and the clients necessary or desired and take care of other administrative details. The X server can actually be started directly, but xinit is usually used to do so and startx is a wrapper to that, as you mention. 'startx' is invoked, it looks to ~/.xinitrc and various other files to see which servers and clients to run, while taking care of other details, and starts them. If you use xdm or the various other ?dms, you're doing something similar, but cutting 'startx' and '.xinitrc' out of the loop and using xdm's configs. But it still boils down to an Xserver and clients.
So startx>xinit>xserver+xclients - done.
My .xinitrc is basically providing values to variables while startx is providing others and invoking the binaries.
I think.
'man' for 'X', 'Xserver', 'xinit', 'startx', 'xdm' for better information. And you can read your '.xinitrc' and 'startx' directly, of course.