Then I don’t understand why maintainers all keep using network.target.
Because most services are able to dynamically accommodate networking changes and act accordingly and it’s rare to have cases where we really need a working link with addresses and a proper connection when the service starts. For those special cases, as described, you need to enable systemd-networkd-wait-online.service and include After=network-online.target and/or Wants=network-online.target in your service.
Programs should be designed to detect and react to networking changes and both Apache and Nginx are good examples of software that does that. There are simpler cases like stuff that needs to bind to non-existent IPs at boot (before networking) that can be dealt with ipv4.ip_nonlocal_bind and net.ipv6.ip_nonlocal_bind as described here.
This may also interest you as it includes what “up” means a few other details: systemd.io/NETWORK_ONLINE/
I still find it a solution desperately looking for a problem to solve.
Systemd does a LOT more than “you can control loads of dependencies”, it solves tons of painful issues and provides a cohesive ecosystem of tools to manage stuff like:
Start services in parallel (while init was one after the other)
Defer service startup until they are actually needed
Replace a bunch of poorly integrated tools such as dhcpcd, dhcpv6, chrony, NetworkManager, resolvconf, logrotate among others with a cohesive ecosystem of tools that are way easier to work with;
Create full fledged containers both privileged and non-privileged here and here while providing tools such as machinectl to manage them.
Systemd is very useful and most people (including myself) don’t know about half of the things it can do. It isn’t teached because of the current poor state of thing when it comes to software development but if you use it you’ll quickly find how to have systems running very well with less processes than conventionally.