When you start out, it will feel very repetitive because your client object structure matches your API structure matches your server object structure. You might even think "DRY!" and want to combine these, but IMO, resist the temptation. You will eventually have a case where these need to evolve independently. For the Galactus case, imagine that for compliance (or whatever) reason, you need to start soft-deleting users, and you do that via the simple case of an `IsDeleted` flag on the User table. You'll need that flag on the User object on the Galactus side, but you don't want to add this to the API and expose it to clients.
> Edit: This allows you to run API migrations and data migrations independently. Which is crucial for any service that will last longer than 1 year.
Totally agreed here too.
I've felt nervous for years about going all-in with Django Rest Framework, and you've articulated exactly why.
But there's also something going over the wire, as a response from Galactus' API, and consumed by one of more other services.
His question was, shouldn't the knowledge of the structure of that be in some type of shared code?
> Imagine I want to fetch user data by id from Galactus, the user data service. I know what shape of data I want from it, and Galactus knows what shape of data it provides. Should both my service and Galactus have full, individual copies of this data structure?
No. Galactus should have the full shape of the "user object" but should never put that on the wire or expose it. The wire API should expose sensible things like "what is the billing and shipping address(es) of this user id". Galactus is responsible for maintaining the mapping between the "user object" and whatever the relevant return format is for those data.
Edit: This allows you to run API migrations and data migrations independently. Which is crucial for any service that will last longer than 1 year.