2
\$\begingroup\$

I am creating an Angular 2 web application using TypeScript. This application performs REST requests to a REST "service". For each REST resource in my service I create a separate "Service" class in Angular2/typescript (e.g., class ServiceA for resource A, class ServiceB for resource B, and so on. Each service class will accept a TypeScript class object that has information about the resource. The user who uses the Service class only deals with resource class instances and not with data serialization etc. All my REST resources support the same actions ('GET', 'POST', etc) and the only difference between them is their api URL and the metadata they might return (right now the 'GET' and 'POST' actions return some metadata in XML format.

The problem is that my REST API has so many resources and I found myself repeating the same Service code again and again. So I decided to refactor the code and have one base Service class that does all the work. Then for each resource I just extend the base class and I also pass the desired serializer through the constructor of the base class. I could ditch the serializer completely and have the serialization code inside the Resource class, but I didn't do so because I want to be able to change the serialization format easily in the future. Furthermore, the service classes that extend the base Service class provide helper functions that do type casting in order to set the correct resource type after the resource creation.

Could you have a look at the code and tell me if I am doing something really wrong? I haven't written any TypeScript or JavaScript in the past and I am afraid that there is a much better solution. In addition I have to mention that initially I tried to use Generics but I kinda failed (Turns out generics are much different than C++ templates). Here is the code:

export class Resource {
}

export class ResourceA extends Resource {
}

// and then ResourceB, ResourceC, and so on.

export class Serializer
{
    public serialize(resource: Resource): string {return null;};
    public deserialize(resourceStr: string): Resource {return null;};
}

export class SerializerA extends Serializer
{
    public serialize(resource: Resource): string {return "serialized resource";};
    public deserialize(resourceStr: string): Resource {return new ResourceA();};
}

// and then SerializerB, SerializerC, and so on.

export class Service
{
    private serializer: Serializer;

    constructor(serializer: Serializer) {
        this.serializer = serializer;
    }

    public getResource(): Resource {
        let incomingData = "some xml or json or whatever.";
        return this.serializer.deserialize(incomingData);
    }

    public postResource(resource: Resource) {
        let outcomingData = this.serializer.serialize(resource);
        // emmit the serialized data string
    }
}

export class ServiceA extends Service
{
    constructor() {
        super(new SerializerA());
    }

    public getResourceOfTypeA(): ResourceA {
        return <ResourceA>this.getResource();
    }

    public postResourceOfTypeA(resource: ResourceA) {
        this.postResource(resource);
    }
}

// and then ServiceB, ServiceC, and so on.

Of course the code is simplified. The full version generates/returns Observables and also uses Angular2's Http module to do the REST/HTTP requests. Any kind of feedback is more than welcome!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.