The summary.
NEVER CHANGE STATE WITH A RETRIEVAL
A link, an image or a crawler can trigger it.
RETURN STATUS CODES THAT MATCH WHAT HAPPENED, AND KEEP EVERY RESPONSE SHAPE CONSISTENT
Returning success for a failure breaks every client, and inconsistency produces defensive code everywhere.
PAGINATE EVERY COLLECTION
An unpaginated endpoint eventually returns everything, and eventually fails.
THE COMMONEST SERIOUS FAULT IS AUTHENTICATION WITHOUT AUTHORISATION
A valid token used to request another user's records by changing an identifier. Verify entitlement to the specific record on every request.
VERSION BEFORE OTHERS DEPEND ON YOU
Adding optional fields is safe; removing, renaming or retyping is not. Decide in advance how many versions you support and for how long.
IN GRAPHQL, ALWAYS SET DEPTH AND COMPLEXITY LIMITS
An unrestricted query can exhaust the server. Batch resolvers, and check entitlement at every field, not only at the top level.
MOST APPLICATIONS NEED A WELL-DESIGNED REST API
Ask which of these problems you actually have before adopting complexity.
GENERATE DOCUMENTATION FROM THE CODE, AND TEST THE EXAMPLES
Hand-written documentation diverges, and broken examples are worse than none.