Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Importing remote interface #23620

Closed
wongjiahau opened this issue Apr 23, 2018 · 5 comments
Closed

[Feature Request] Importing remote interface #23620

wongjiahau opened this issue Apr 23, 2018 · 5 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints

Comments

@wongjiahau
Copy link

Preface

Microservices are the current trend nowadays in building application. However, it has one major drawback as mentioned by Martin Fowler in this article, "It is hard to defined a PUBLISHED INTERFACE ". Thus, developers that adopt to microservices often rely heavily on documentation and discipline to make sure API calls work properly.
However, due to the fact that client's requirement is ever changing, developers have to constantly update documentation for updated API, and this will cause developers to have high cognitive stress, as they have to eventually memorize the JSON structure of each API call, thus decreasing their efficiency in coding.

Objective

This feature request is to solve the problem of published interface (as mentioned in Preface) by leveraging the type-checking system in Typescript.
Moreover, those interface file(s) itself will serve as the documentation, so developers won't have to update some non-code documentation when they make changes to an API.

Proposal

Suppose we have to following interfaces defined in a file called myInterfaces.ts :

export interface IApiResponse {
    success: boolean;
    data: IPeople[];
}

export interface IPeople {
    name: string;
    age: number;
}

Also, imagine that this file is hosted on Github and can be retrieved at this imaginary link : https://raw.githubusercontent.com/john/myservice/master/myInterfaces.ts.

How to import them?

Now, let say we have a file in another project that will need to import these interfaces. So, here's how we do it.

import {IApiResponse, IPeople} from 
	"https://raw.githubusercontent.com/john/myservice/master/myInterfaces.ts";

request('http://bla.com/api/get', 
    (err, res, body: IApiResponse) => { 
	const people = body.data; // Intellisene will be triggered when you type the dot
}

So, that is how you do it.

Possible problems

  • The URL is not giving back any response
  • The responded file has syntax error
  • Import error (e.g. using {} to import export default module)

These problems should be reporeted to user by the compiler.

How it works?

As soon as you finished typing the URL in the import statement, the compiler will start to fetch the file and stored it in a the .remoteInterfaces hidden folder.
Note that the files within the .remoteInterfaces are read-only, thus you cannot modify them at your will.

Q & As

1. I thought we have some others methods to resolve this problem?

Yes, of course we do, for example, you can solve this problem with some directory hack.

├── published_interfaces
│    ├── interface1.ts
│    └── interface2.ts
├── service1
│    └── ...
├── service2
│    └── ... 
└── service3
     └── ... 

But this is not really practical, because in real scenario we would want to separate all the services into their own repository. If we use this approach we will eventually face some git pull or git push chaos.

2. Does it support Typescript Design Goals?

This feature request support Goal #1 : "Statically identify constructs that are likely to be errors.". This is because developers will often deconstruct the JSON response from an API wrongly. With this feature this kind of error can be identified statically.

3. Is the remotely downloaded interface cached?

I believe that this is not necessary in the current implementation, unless you have really spiky internet connection. Thus, for every cycle of compilation those remote interfaces will be fetched to make sure the current project adhere to the latest implementation of those interfaces.

4. Must I host those interfaces at Github?

Not necessary, you can host them in your own server as well.

5. Can I view the definition of the remote interface?

Yes, because the downloaded interfaces will be store in a temporary directory called .remoteInterfaces.

Related issues/projects

Conclusion

I believe that this is not only my dream feature, many other microservice-oriented developers would love this feature too.
I will create a pull request to have this feature implemented as soon as this issue is listed on the milestone.

@MartinJohns
Copy link
Contributor

I'm really not sure that this is a good approach. Why aren't you just using NPM packages? That already works today™ and integrates well into the existing eco-system. Whenever your microservice is deployed, automatically deploy a corresponding NPM package with the updated types. Then have an automated task that will update the NPM package in your project and create a Merge/Pull Request.

@wongjiahau
Copy link
Author

@MartinJohns I had thought of that too, but I think it's quite overkill because all you wanted is to published some interfaces. Not only that, you need to go through some mental burden on how to publish npm package.
Furthermore, using npm will not tackle one of the problem stated in Preface: that is developer have to modify two things whenever they want to change an API. Because not only they have to handle documentation, they also need to make sure the published package is updated.
But with the importing remote interface approach, all the developers have to change is the interface file, no more burden to make sure documentation are updated.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 23, 2018

Just to be clear, given a .d.ts defining the shape of a module the typescript compiler will check your code against it.

The question here is how to distribute these declaration files. npm is one option, and you do not even need to publish to npm, you can just use a github branch as a dependency in your package.json.

Other alternatives is to have a script to download them for you, and use path mapping to tell the compiler how to resolve them.

Ultimately, this is a configuration/distribution issue. i do not think the typescript compiler (or any compiler for that matter) should be involved in downloading files from a remote source.

@mhegazy mhegazy added the Out of Scope This idea sits outside of the TypeScript language design constraints label Apr 23, 2018
@wongjiahau
Copy link
Author

wongjiahau commented Apr 24, 2018

@mhegazy Thanks for the suggestion regarding using Github branch as dependency. This approach does not solve the problem that developer need to handle more than one thing. Because by using the method you mentioned, developer have to make sure it committed the right file to the right branch, and he/she must make sure the branch is pushed to Github.

C'mon, you should able to automate that by writing some scripts. Hello guys, isn't this another mental burden? How sure are you your scripts work properly?

As developers we want to focus on building things, not wasting much effort on configuring things. (That's why Docker emerges!)

All we want is to share an interface file between two different repos easily.

Lastly, I don't understand why is this out of scope as it does not violates any of the design goal, and it even fulfills some of the design goal.

Martin Fowler even quoted, "Most languages do not have a good mechanism for defining an explicit Published Interface.".

Thus, I believe this will be a breakthrough in the coding industry if Typescript will have this feature.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints
Projects
None yet
Development

No branches or pull requests

4 participants