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

C# and JavaScript Static Client Proxy Generation #9864

Closed
hikalkan opened this issue Aug 20, 2021 · 2 comments · Fixed by #9905
Closed

C# and JavaScript Static Client Proxy Generation #9864

hikalkan opened this issue Aug 20, 2021 · 2 comments · Fixed by #9905

Comments

@hikalkan
Copy link
Member

ABP's dynamic client proxy (for c# and for javascript) system creates the proxies on runtime. With this issue, we are planning to build an alternative system that creates the client proxy code in development time. We are already doing it for angular with the abp generate-proxy command (see doc). We will create a similar system for c# client proxies (that is typically used by the Blazor UI and tiered MVC applications) and javascript client proxies (for mvc UI, while calling APIs from the JavaScript code).

ABP CLI's same abp generate-proxy command will be used. We can get a parameter (like -t JavaScript or -t csharp) to indicate the language. To generate a client code, we should first run the server application in our development environment. It exposes the api/abp/api-definition endpoint. ABP CLI will use this endpoint to get the API definition (like the current Angular code generation) and create the client code.

This feature naturally solves that problem. So, we no longer need to add HTTP API layers of microservices to API gateways to be able to create api/abp/api-definition endpoint with all the service definitions included. Client will already have the necessary proxy code to call the API. When it calls, Ocelot (or another gateway) will already forward request to the corresponding microservice (this is already working now).

Note that we won't remove the dynamic client system. It will remain in v5.0 just as before, to be backward compatible. With this new feature, we will have two ways to create dynamic client proxies: 1) dynamically on runtime 2) statically on development.

C# Client Proxy Generation Notes

I will typically run this command in the directory of the *.HttpApi.Client project in the startup solution:

abp generate-proxy --type csharp --module identity --url https://localhost:8292 
  • Shortcut for --type is -t. Required.
  • Shortcut for --module is -m. This value is matched with the module name in modules dictionary of the API definition. Optional, assumed app if not provided.
  • --url is the URL of the server-side application. It should be running while executing this command. Required.

Implementation Notes

  • Name clients like UserClientProxy for UserController.
  • Derive the client proxy from a common class, like ClientProxyBase that is defined in Volo.Abp.Http.Client package.
  • Implement the corresponding interface of the controller, like IUserAppService. Create only the methods of that interface. The controller may have more methods, but we don't want to create proxy methods for the methods not defined by that interface. Also, this interface should be available in the client side. We don't want to create interfaces or DTO types defined in the service methods, they should be available on the client side (it has a reference to the Application.Contracts package, so the types should already be available there).
  • Create the client class partial and leave an empty partial to the developer, so they may want to add custom methods.
  • Place all the client classes into ClientProxies namespace by default. We can get the folder name as a parameter, like --folder MyProxies/InnerFolder.
  • Try to keep method bodies of the proxy client classes minimal, delegate the actual work to base class methods.

JavaScript Client Proxy Generation Notes

I will run this command in the directory of the web project:

abp generate-proxy --type js --module identity --url https://localhost:8292 

Implementation Notes

  • Every module should be generated in a separate JavaScript file, like identity-proxy.js under wwwroot/client-proxies folder by default.
  • We can get the full output path as a parameter, like --out Pages/Identity/client-proxies.js .
@XuJin186
Copy link

Can you provide a rewriting mechanism so that we can also quickly reuse most of the logic to generate proxies in other languages, such as Dart

@hikalkan
Copy link
Member Author

hikalkan commented Sep 2, 2021

@XuJin186 for other languages, we currently suggest to use NSWAG tool that creates client proxies based on Swagger endpoints. We will consider your suggestion, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants