String owns heap-allocated bytes and can grow. &str is a borrowed view into bytes someone else owns — a pointer and a length, no allocation.
For parameters, the rule is nearly always: take &str.
A caller with a String can pass &s and deref coercion handles it, while a caller with a literal passes it directly. Taking String forces every caller to allocate or give up ownership for no reason.
Return String when you are producing new text, as above. Return &str only when it borrows from an input, and the lifetimes will say so.