Table of Contents

Creating a server method

In this article, we will detail the creation of a method that retrieves the number of available units of a product.

Creating the required properties

For this example, you need to add two properties to the Product entity.

UnitsInStock :

Name = UnitsInStock
Caption = Units in stock
Data type = Decimal

UnitsOnOrder :

Name = UnitsOnOrder
Caption = Units on order
Data type = Decimal

To be able to use the new properties during the next step, you first need to generate the metadata for the entity and generate the application. If you have forgotten how to do it, click here. You must also add these new fields in the ProductUI template in order to feed them:

<form-field property-name="UnitsInStock" />
<form-field property-name="UnitsOnOrder" />

Generate the application and open https://localhost/neos/Northwind, go to the products screen and fill the UnitsInStock and UnitsOnOrder on your products.

Defining what the server method returns

Before creating the server method, it is necessary to define what it will return. To do this, you will use a Data object. Data objects are versatile and can be used by several elements of Neos Studio, not just server methods. In this example, you are going to create a data object that will contain the number of available units of a product.

In the menu, deploy the Catalog module, click on Shared and click on the + button next to the Data objects item to create the following data object :

Data object name = AvailableUnitsResult
Description = Available units result

Add the following element in the Properties table:

Name = AvailableUnits
Description = Available units
.NET data type = double

Creating the server method metadata

In the menu, deploy the Catalog module, click on Backend and click on the + button next to the Server methods item to create the following method :

Name = GetAvailableUnits

Check Expose as API in the global screen after validating the creation pop-up.

Use the Code property to define in C# the server method signature:

/// <inheritdoc/>
public async System.Threading.Tasks.Task<Northwind.Application.Abstractions.DataObjects.AvailableUnitsResult> ExecuteAsync(int productID)
{
}

The signature is used to define the type of return as well as the parameters to pass. Save the server method. This generates a new class in the application project :

Catalog
└─── businessAssembly
     └─── Application
         └─── ServerMethods
              │   GetAvailableUnits.cs

You will need the product repository in order to retrieve the product from its identifier. For this, it is necessary to add a dependency to the server method. Click on the dedicated button available at the top right of the editor code. Click on the Add button and fill properties as follows :

Dependency type = Entity view repository
Entity view name = ProductView

The dependencies defined in this array are injected into the constructor of the C# class associated with the server method. You can now define the method content using the injected repository:

IProductView product = await _productViewRepository.GetAsync(productID);

return new Northwind.Application.Abstractions.DataObjects.AvailableUnitsResult()
{
    AvailableUnits = Math.Max((double)((product?.UnitsInStock ?? 0) - (product?.UnitsOnOrder ?? 0)), 0.0),
};
Note

This example is intentionally very simple. You could enhance it by adding an ErrorMessage string property to the AvailableUnitsResult data object and set its value in the GetAvailableUnits server method when the product is not found.

Save the changes and generate the application.

Calling the server method

You will now see how to call your server method.

From swagger

Because we checked Expose as API in the properties of the server method, the generated application automatically exposes it.

Run the application and open https://localhost/neos/Northwind/swagger/index.html in your web browser:

Your server method appears in the list of available APIs. You can click on it and use the "Try it out" button to test it.

From a button in the UI

You can also directely call this API using a button in the UI.
For this, you need to create an action in the Actions tab of the ProductUI

Name = GetAvailableUnits
Caption = Get available units

Location = Toolbar
Position = 1

Action type = Code

You will use the Code property to define in C# the action content :

if (DatasourceCurrent != null)
{
    AvailableUnitsResult result = await this.ServerMethods.GetAvailableUnits.ExecuteAsync(DatasourceCurrent.ProductID);
    string message = string.Format(Resources.Catalog.NumberAvailableUnitsProduct, DatasourceCurrent.ProductName, result.AvailableUnits);
    await ShowMessageAsync(MessageType.Positive, "GetAvailableUnits", message);
}

Save the changes.

Warning

You may encounter a generation error at this point if you named your properties with a different name or case than in the examples.
If that is the case, use intellisense suggestions (Ctrl + Space) in the code editor to update the name of the properties of the DatasourceCurrent property.

Now, you have a button in the toolbar of the product edit screen that calls the server method and displays its response.

Advanced server method with TDD method

For an example of server method implementation following the TDD method, you can refer to this article.