As you say, if you want to have 0-RTT data, you must have some prior information about the server. This information can come in two main forms.
1. Have the client know the server's public key in advance. You can then do a RSA or ephemeral-static key exchange, as in gQUIC, OPTLS, or TLS Fasttrack.
2. Have the client and the server do an initial handshake and then reuse the symmetric key for future connections, as in TLS 1.3 and IETF QUIC (which uses TLS 1.3).
The public key version has a number of superficially compelling properties, in particular that you can publish the server's data somewhere like DNS ("0-RTT Priming") and thus have 0-RTT with the first connection. By contrast with the symmetric version you have to have a connection first. The public key mode also will work in this setting. However, making this work in practice has a number of challenges around authentication, anti-replay, anti-amplification, etc. Initially TLS 1.3 had both of these modes but we ultimately removed the public-key based one in favor of a symmetric-key based mode.
1. Have the client know the server's public key in advance. You can then do a RSA or ephemeral-static key exchange, as in gQUIC, OPTLS, or TLS Fasttrack. 2. Have the client and the server do an initial handshake and then reuse the symmetric key for future connections, as in TLS 1.3 and IETF QUIC (which uses TLS 1.3).
The public key version has a number of superficially compelling properties, in particular that you can publish the server's data somewhere like DNS ("0-RTT Priming") and thus have 0-RTT with the first connection. By contrast with the symmetric version you have to have a connection first. The public key mode also will work in this setting. However, making this work in practice has a number of challenges around authentication, anti-replay, anti-amplification, etc. Initially TLS 1.3 had both of these modes but we ultimately removed the public-key based one in favor of a symmetric-key based mode.