Since you are asking about REST, then I assume that your "model" means a set of classes implementing common representations.
In other words, you are asking if it is OK to share the source code of DTO classes for Json or XML serialization.
(If you are asking about entity/domain implementation, then absolutely DON'T DO THIS - the server and the client almost always have different assumptions about such simple concepts as "Order" and "Item".)
Here are some arguments against sharing the code of an API, (assuming the client and the server are owned by different teams):
The centralization of protocol specification is a dangerous illusion
Even if your services are compiled daily against common-dtos-SNAPSHOT.jar, you don't control the order in which the services actually reach the production.
Therefore, you should always think of forward and backwards compatibility - can a server talk to an old version of a client? Can a new client talk to an old server?
Having a centralized place for the code creates an illusion for developers that all machines work in an idealised world.
Repositories with the common API code end up being owned by no team.
There's a missing getter in a DTO - I can create a merge request, but there's literally noone in the organization who can merge it and relase a new version of the library.
The perceived maintanance benefits aren't real, they are more about aestethics
Copying&pasting code between services feels ugly, but it takes like an hour max, where the total cost of maintaining various operational dependencies adds up unnoticeably.
Let me quote Sam Newman's "Building Microservices: Designing Fine-Grained Systems":
DRY and the Perils of Code Reuse in a Microservice World
One of the acronyms we developers hear a lot is DRY: don’t repeat yourself. Though its definition is sometimes simplified as trying to avoid duplicating code, DRY more accurately means that we want to avoid duplicating our system behavior and knowledge. This is very sensible advice in general. Having lots of lines of code that do the same thing makes your codebase larger than needed, and therefore harder to reason about. When you want to change behavior, and that behavior is duplicated in many parts of your system, it is easy to forget everywhere you need to make a change, which can lead to bugs. So using DRY as a mantra, in general, makes sense.
DRY is what leads us to create code that can be reused. We pull duplicated code into abstractions that we can then call from multiple places. Perhaps we go as far as making a shared library that we can use everywhere! This approach, however, can be deceptively dangerous in a microservice architecture.
One of the things we want to avoid at all costs is overly coupling a microservice and consumers such that any small change to the microservice itself can cause unnecessary changes to the consumer. Sometimes, however, the use of shared code can create this very coupling. For example, at one client we had a library of common domain objects that represented the core entities in use in our system. This library was used by all the services we had. But when a change was made to one of them, all services had to be updated. Our system communicated via message queues, which also had to be drained of their now invalid contents, and woe betide you if you forgot.
If your use of shared code ever leaks outside your service boundary, you have introduced a potential form of coupling. Using common code like logging libraries is fine, as they are internal concepts that are invisible to the outside world. RealEstate.com.au makes use of a tailored service template to help bootstrap new service creation. Rather than make this code shared, the company copies it for every new service to ensure that coupling doesn’t leak in.
My general rule of thumb: don’t violate DRY within a microservice, but be relaxed about violating DRY across all services. The evils of too much coupling between services are far worse than the problems caused by code duplication. There is one specific use case worth exploring further, though.
I’ve spoken to more than one team who has insisted that creating client libraries for your services is an essential part of creating services in the first place. The argument is that this makes it easy to use your service, and avoids the duplication of code required to consume the service itself.
The problem, of course, is that if the same people create both the server API and the client API, there is the danger that logic that should exist on the server starts leaking into the client. I should know: I’ve done this myself. The more logic that creeps into the client library, the more cohesion starts to break down, and you find yourself having to change multiple clients to roll out fixes to your server. You also limit technology choices, especially if you mandate that the client library has to be used.