I suggest that you review Jim Webber's 2011 talk.
If we are doing REST, then we are achieving our goals using general purpose message semantics. When HTTP is our application of choice, then our general purpose message semantics are those associated with transferring documents over a network.
You deliver information to a system by proposing changes to a resource.
One common form of change is a modification of a representation of the resource. In your case, that would suggest a resource that is a list of all categories associated with the product. So you would GET
the current representation of that resource, make local changes to your copy, then PUT
your updated representation back to the same resource.
GET /products/1/categories
200 OK
Content-Type: text/plain
A
B
C
D
PUT /products/1/categories
Content-Type: text/plain
A
B
E
F
G
200 OK
When the representation of the resource is very large (relative to the size of the HTTP headers), and the edits you want to support are often going to be small, then it can make sense to support PATCH, accepting one of the standardized patch document formats.
The other approach is to POST to the resource a document that describes some change to be made. See It is okay to use POST, by Roy Fielding:
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
This is how most of the pre-javascript HTML web worked; HTML forms would tell clients how to create an application/x-www-form-urlencoded
document that the target resource would know how to interpret.
POST /products/1/categories
Content-Type: application/x-www-form-urlencoded
remove=C,D&add=E,F,G
and that worked great; the web was catastrophically successful.
Forms work because the text/html media type has a standardized definition of forms, and how to process them. You can do something similar with your own media types; defining within the representations how to find interesting links that advertise the capabilities of some resource.
Another approach is to use [web links]; you define the semantics of a link relation
the relation http://example.org/abc
indicates that the target resource is capable of understanding and handling POST requests containing application/prs.xyz+json
documents)
And then you embed those link relations either into your representations, into the HTTP headers, or both. Then any client that understands the semantics of the link relation and the associated media types will be able to take advantage of the advertised capability.
See RFC 5023 to see how this approach was applied in Atom.