From 81ca8497332399d258f3ffc384c96dcc934a4f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Mon, 18 Apr 2022 19:15:29 +0300 Subject: [PATCH 1/2] Documented "Static JavaScript API Client Proxies" --- .../AspNetCore/Dynamic-JavaScript-Proxies.md | 14 +- .../AspNetCore/Static-JavaScript-Proxies.md | 157 ++++++++++++++++++ docs/en/images/static-js-proxy-example.png | Bin 0 -> 6899 bytes 3 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 docs/en/UI/AspNetCore/Static-JavaScript-Proxies.md create mode 100644 docs/en/images/static-js-proxy-example.png diff --git a/docs/en/UI/AspNetCore/Dynamic-JavaScript-Proxies.md b/docs/en/UI/AspNetCore/Dynamic-JavaScript-Proxies.md index 3464d4bc68..31c2dbe7ea 100644 --- a/docs/en/UI/AspNetCore/Dynamic-JavaScript-Proxies.md +++ b/docs/en/UI/AspNetCore/Dynamic-JavaScript-Proxies.md @@ -1,6 +1,12 @@ # Dynamic JavaScript API Client Proxies -It is typical to consume your HTTP APIs from your JavaScript code. To do that, you normally deal with low level AJAX calls, like $.ajax, or better [abp.ajax](JavaScript-API/Ajax.md). ABP Framework provides **a better way** to call your HTTP APIs from your JavaScript code: Dynamic JavaScript API Client Proxies! +It is typical to consume your HTTP APIs from your JavaScript code. To do that, you normally deal with low level AJAX calls, like $.ajax, or better [abp.ajax](JavaScript-API/Ajax.md). ABP Framework provides **a better way** to call your HTTP APIs from your JavaScript code: JavaScript API Client Proxies! + +## Static vs Dynamic JavaScript Client Proxies + +ABP provides **two types** of client proxy generation system. This document explains the **dynamic client proxies**, which generates client-side proxies on runtime. You can also see the [Static JavaScript API Client Proxies](Static-JavaScript-Proxies.md) documentation to learn how to generate proxies on development time. + +Development-time (static) client proxy generation has a **slight performance advantage** since it doesn't need to obtain the HTTP API definition on runtime. However, you should **re-generate** the client proxy code whenever you change your API endpoint definition. On the other hand, dynamic client proxies are generated on runtime and provides an **easier development experience**. ## A Quick Example @@ -55,7 +61,7 @@ acme.bookStore.authors.author ## AJAX Details -Dynamic JavaScript client proxy functions use the [abp.ajax](JavaScript-API/Ajax.md) under the hood. So, you have the same benefits like **automatic error handling**. Also, you can fully control the AJAX call by providing the options. +JavaScript client proxy functions use the [abp.ajax](JavaScript-API/Ajax.md) under the hood. So, you have the same benefits like **automatic error handling**. Also, you can fully control the AJAX call by providing the options. ### The Return Value @@ -86,6 +92,6 @@ The magic is done by the `/Abp/ServiceProxyScript` endpoint defined by the ABP F ## See Also -* [Web Application Development Tutorial](../../Tutorials/Part-1.md) +* [Static JavaScript API Client Proxies](Static-JavaScript-Proxies.md) * [Auto API Controllers](../../API/Auto-API-Controllers.md) -* [Dynamic C# API Client Proxies](../../API/Dynamic-CSharp-API-Clients.md) \ No newline at end of file +* [Web Application Development Tutorial](../../Tutorials/Part-1.md) \ No newline at end of file diff --git a/docs/en/UI/AspNetCore/Static-JavaScript-Proxies.md b/docs/en/UI/AspNetCore/Static-JavaScript-Proxies.md new file mode 100644 index 0000000000..20b87aa89b --- /dev/null +++ b/docs/en/UI/AspNetCore/Static-JavaScript-Proxies.md @@ -0,0 +1,157 @@ +# Static JavaScript API Client Proxies + +It is typical to consume your HTTP APIs from your JavaScript code. To do that, you normally deal with low level AJAX calls, like $.ajax, or better [abp.ajax](JavaScript-API/Ajax.md). ABP Framework provides **a better way** to call your HTTP APIs from your JavaScript code: JavaScript API Client Proxies! + +## Static vs Dynamic JavaScript Client Proxies + +ABP provides **two types** of client proxy generation system. This document explains the **static client proxies**, which generates client-side code in your development time. You can also see the [Dynamic JavaScript API Client Proxies](Dynamic-JavaScript-Proxies.md) documentation to learn how to use proxies generated on runtime. + +Development-time (static) client proxy generation has a **slight performance advantage** since it doesn't need to obtain the HTTP API definition on runtime. However, you should **re-generate** the client proxy code whenever you change your API endpoint definition. On the other hand, dynamic client proxies are generated on runtime and provides an **easier development experience**. + +## A Quick Example + +### The Application Service + +Assume that you have an application service defined as shown below: + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Acme.BookStore.Authors +{ + public interface IAuthorAppService : IApplicationService + { + Task GetAsync(Guid id); + + Task> GetListAsync(GetAuthorListDto input); + + Task CreateAsync(CreateAuthorDto input); + + Task UpdateAsync(Guid id, UpdateAuthorDto input); + + Task DeleteAsync(Guid id); + } +} +```` + +> You can follow the [web application development tutorial](../../Tutorials/Part-1.md) to learn how to create [application services](../../Application-Services.md), expose them as [HTTP APIs](../../API/Auto-API-Controllers.md) and consume from the JavaScript code as a complete example. + +### Generating the JavaScript Code + +Server side must be up and running while generating the client proxy code. So, first run the application that hosts your HTTP APIs (can be the Web application or the HttpApi.Host application depending on your solution structure). + +Open a command-line terminal in the root folder of your web project (`.csproj`) and type the following command: + +````bash +abp generate-proxy -t js -u https://localhost:53929/ +```` + +> If you haven't installed yet, you should install the [ABP CLI](../CLI.md). Change the example URL to your application's root URL. + +This command should generate the following files under the `ClientProxies` folder: + +![static-js-proxy-example](../../images/static-js-proxy-example.png) + +`app-proxy.js` is the generated proxy file in this example. Here, an example proxy function in this file: + +````js +acme.bookStore.authors.author.get = function(id, ajaxParams) { + return abp.ajax($.extend(true, { + url: abp.appPath + 'api/app/author/' + id + '', + type: 'GET' + }, ajaxParams)); +}; +```` + +> `generate-proxy` command generates proxies for only the APIs you've defined in your application (assumes `app` as the module name). If you are developing a modular application, you can specify the `-m` (or `--module`) parameter to specify the module you want to generate proxies. See the *generate-proxy* section in the [ABP CLI](../CLI.md) documentation for other options. + +### Using the Proxy Functions + +To use the proxy functions, first import the `app-proxy.js` file into your page: + +````html + +```` + +> We've used the [abp-script tag helper](Bundling-Minification.md) in this example. You could use the standard `script` tag, but the `abp-script` is the recommended way of importing JavaScript files to your pages. + +Now, you can call any of the application service methods from your JavaScript code, just like calling a JavaScript function. The JavaScript function has the identical function **name**, **parameters** and the **return value** with the C# method. + +**Example: Get a single author** + +````js +acme.bookStore.authors.author + .get("7245a066-5457-4941-8aa7-3004778775f0") //Get id from somewhere! + .then(function(result){ + console.log(result); + }); +```` + +**Example: Get the authors list** + +````js +acme.bookStore.authors.author.getList({ + maxResultCount: 10 +}).then(function(result){ + console.log(result.items); +}); +```` + +**Example: Delete an author** + +```js +acme.bookStore.authors.author + .delete('7245a066-5457-4941-8aa7-3004778775f0') //Get id from somewhere! + .then(function() { + abp.notify.info('Successfully deleted!'); + }); +``` + +## Disabling Dynamic JavaScript Proxies + +When you create an application or module, the [dynamic client proxy generation](Dynamic-JavaScript-Proxies.md) approach is used by default. If you want to use the statically generated client proxies for your application, you should explicitly disable it for your application or module in the `ConfigureServices` method of your [module class](../../Module-Development-Basics.md) as like in the following example: + +````csharp +Configure(options => +{ + options.DisableModule("app"); +}); +```` + +`app` represents the main application in this example, which works if you are creating an application. If you are developing an application module, then use your module's name. + +## AJAX Details + +JavaScript client proxy functions use the [abp.ajax](JavaScript-API/Ajax.md) under the hood. So, you have the same benefits like **automatic error handling**. Also, you can fully control the AJAX call by providing the options. + +### The Return Value + +Every function returns a [Deferred object](https://api.jquery.com/category/deferred-object/). That means you can chain with `then` to get the result, `catch` to handle the error, `always` to perform an action once the operation completes (success or failed). + +### AJAX Options + +Every function gets an additional **last parameter** after your own parameters. The last parameter is called as `ajaxParams`. It is an object that overrides the AJAX options. + +**Example: Set `type` and `dataType` AJAX options** + +````js +acme.bookStore.authors.author + .delete('7245a066-5457-4941-8aa7-3004778775f0', { + type: 'POST', + dataType: 'xml' + }) + .then(function() { + abp.notify.info('Successfully deleted!'); + }); +```` + +See the [jQuery.ajax](https://api.jquery.com/jQuery.ajax/) documentation for all the available options. + +## See Also + +* [Dynamic JavaScript API Client Proxies](Dynamic-JavaScript-Proxies.md) +* [Auto API Controllers](../../API/Auto-API-Controllers.md) +* [Web Application Development Tutorial](../../Tutorials/Part-1.md) \ No newline at end of file diff --git a/docs/en/images/static-js-proxy-example.png b/docs/en/images/static-js-proxy-example.png new file mode 100644 index 0000000000000000000000000000000000000000..575957b9ae2bbfb493b0101eca8c0d39b036b81e GIT binary patch literal 6899 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 Date: Mon, 18 Apr 2022 19:16:54 +0300 Subject: [PATCH 2/2] Added Static JavaScript API Client Proxies to the documentation menu. --- docs/en/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 8c08724b62..b2061920a8 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -647,6 +647,10 @@ "text": "Dynamic JavaScript API Client Proxies", "path": "UI/AspNetCore/Dynamic-JavaScript-Proxies.md" }, + { + "text": "Static JavaScript API Client Proxies", + "path": "UI/AspNetCore/Static-JavaScript-Proxies.md" + }, { "text": "Client Side Package Management", "path": "UI/AspNetCore/Client-Side-Package-Management.md"