Wednesday, July 15, 2015

Pattern for Model Objects in TypeScript

So here is a pattern that my team has come to agree on over time, but not always used. I am putting in my blog more as a way to cement it in my mind as the appropriate pattern.

The problem is model objects and team construction. Our team is divided between web client and server people. This leads to a thick 'architectural' line between the two. This means that the model objects we want to use in the client aren't always what the server produces. The server code can change and immediately demand that the client team rapidly adapt.

The pattern we have is to have Model objects for the objects we want to use. Since we are using TypeScript we have interfaces and we use them to define the JSON going back and forth to the server. The model object constructor has a signature like:

constructor(serverJSON?: IServerApi) { ... }

If nothing is passed in we assume you are creating a new object on the client. If something is passed in we assume it has structure as defined in the contract. We then copy over and modify whatever values we want. Now because there is no enforcement of this interface with what the server actually sends this can be wrong. However, the interface is a very nice place for the web client team to define what we expect from the server. If the server changes then we can reflect that in the interface and then let the changes flow through our system.

Now this offers one way conversion to the model object, but we also have conversion of our model objects to server objects. We do this like so:

public convertToServer(): IAnotherServerApi { ... }

This outputs an object that meets the interface, but that doesn't have a constructor. This is JavaScript so you don't need a constructor to make an object.

Now all my server contracts are embodied in a set of interfaces. All my object transformation code is nicely contained within the objects themselves and I don't create a useless API object class.

No comments:

Post a Comment