Thank you for your interest in using SpatialOS!
My answer will be opinion based, the best practice will depend on the different requirements of the game, or how far you may be willing to go towards optimization.
For dodgeable bullets I would start prototyping with using an entity per bullet, get a good feel for the gameplay, then I would optimize it afterwards - with higher urgency especially if you find out that it’s causing performance issues.
For them to be dodgeable they would probably be moving relatively slowly so you can see them and react. This means they will have a lifetime that’s more than a few frames for sure, which justifies them being entities a bit more.
If you use the GDK for Unity’s transform synchronization module or something similar to it, you can implement this relatively trivially: add in the relevant components into the entity template, spawn them, and in the behaviour scripts set a velocity. As they use this velocity the positions will be updated in all server and client workers. You can handle the rigid body collisions and do some damage that way. You can handle the lifetime by noting down when they were created, how long they should be living, and comparing that with current time every frame. Then you can destroy the entity.
Some optimization would be for example to have multiple bullets as one entity (e.g. a burst of bullets). For that one, you may need to implement your own position synchronization behaviour for each bullet - this because currently the transform synchronization module acts per entity only.
Another would be to represent them as events from the shooting characters or objects, then the clients and the server could do a local simulation for the movement and the interaction. Every optimization step would mean you would be implementing more of the simulation yourself. For example each client would be performing the movement logic only locally - no information would be sent after the shot unless the bullets had actually hit something on the server. Then the server worker would send events and/or commands to other workers to signify that “something happened”. One problem with this is if you happen to check out this owning entity after a bullet had been “shot”, you may not have received that event, so information about recent bullets may need to be stored on this entity, and so on.
I hope this helps!