Extending standard APIs (1)

I’ve got this question so many times: how can we extend the standard APIs with extra fields? So I decided to write a blog post about it. Actually, it’s going to be two blog posts, because one would become too long. So here it goes…

This could be a very short blog post.  Microsoft disabled the option to customize the standard APIs in Business Central. Full stop…

No, of course not!!!

In this first blog post I want to cover the easy scenario: add a missing field to an API for master data. With master data, I mean for example the customers or items API. Those API pages are directly based on the table, while transaction APIs like sales orders are based on a buffer table. That makes it more complex to add extra fields. But not impossible! Just a little more complex. That will be for the next blog post. Let’s first focus on adding an extra field to the customers API.

The scenario

Let’s say we have a table extension for the customer table with two fields: Shoe Size and Hair Color. And we want these two fields to be added to the customers API. This is the table extension for the Customer table:

tableextension 50100 CustomerAJK extends Customer
{
    fields
    {
        field(50100; ShoeSizeAJK; Integer)
        {
            Caption = 'Shoe Size';
        }
        field(50101; HairColorAJK; Text[30])
        {
            Caption = 'Hair Color';
        }
    }
}

Creating the API page

Because it is not possible to create a page extension for a standard customers API, the only option is to copy it and make it our own. The downside of this is that we always need to keep it in sync with the standard API as released by Microsoft. If you want to keep it exactly the same of course. But we should not forget that APIs never get breaking changes. Instead, a new API version will be released alongside the existing API. And that does not happen with every release of Business Central. In other words, there is not a big risk involved.

How can we get the code of the standard APIs? That’s pretty simple: just clone the GitHub repository https://github.com/microsoft/ALAppExtensions. The app with the standard APIs v2 is in the folder Apps/W1/APIV2/app. If you open that folder in VS Code, then you will get many errors because the symbol files are missing. Just download symbol file to get rid of those errors.

Find the file APIV2Customers.Page.al in the APIV2 app and copy it to the app that has the extra fields. Next step is to make some corrections:

  • Change the object ID so it fits in your object range
  • Change the object name and the file name according to your naming conventions
  • Add the APIPublisher and APIGroup property
  • Optionally, modify the APIVersion property. This also depends on how you solve the remaining errors in the page about missing page parts (see below)
  • Optionally, reorder the page properties (that’s just my preference, to order them more logically)
  • Optionally, fix the implicit with warnings (to get rid of warnings during the build)

The properties of the API page now look like this:

page 50100 CustomersAPIv1AJK
{
    PageType = API;
    APIPublisher = 'ajk';
    APIGroup = 'demo';
    APIVersion = 'v2.0';
    EntitySetName = 'customers';
    EntityName = 'customer';
    EntitySetCaption = 'Customers';
    EntityCaption = 'Customer';
    ChangeTrackingAllowed = true;
    DelayedInsert = true;
    ODataKeyFields = SystemId;
    SourceTable = Customer;
    Extensible = false;

Fixing compilation errors

The page is also showing some compilation errors about missing page parts. There are a number of related entities, like customerFinancialDetails that are missing. These parts are in the APIV2 app. There are three options to solve these errors.

Option 1 is to just remove the related parts. If you don’t need them, then that’s the simplest solution of course.

Option 2 is to copy the missing page parts. That means that you have to do the same fixes as with the customers API. In fact, you are copying a complete set of API pages that belong to each other.

Option 3 is my preference: set a dependency on the APIV2 app. Then you don’t have to copy the missing page parts. If you choose this option, then there is one requirement: the property APIVersion of your custom API page must be the same as in the related API page from the depending app. That’s why I left it to v2.0 in the example above. The dependencies part in the app.json looks like this:

  "dependencies": [
    {
      "id":  "10cb69d9-bc8a-4d27-970a-9e110e9db2a5",
      "name":  "_Exclude_APIV2_",
      "publisher":  "Microsoft",
      "version":  "17.4.0.0"
    }
  ]

Adding the custom fields

Now we have a new custom API page that is an exact copy of the original one. The only step left is to add the two new fields. This is done by adding these lines to the field list:

                field(shoeSize;Rec.ShoeSizeAJK)
                {
                    Caption = 'Show Size';

                    trigger OnValidate()
                    begin
                        RegisterFieldSet(Rec.FieldNo(ShoeSizeAJK));
                    end;
                }
                field(hairColor;Rec.HairColorAJK)
                {
                    Caption = 'Hair Color';

                    trigger OnValidate()
                    begin
                        RegisterFieldSet(Rec.FieldNo(HairColorAJK));
                    end;
                }

Note the extra code line on the OnValidate, with the call to RegisterFieldSet. This is necessary, because of a pattern that is used in some standard API pages. After the record has been inserted the API page calls a function ProcessNewRecordFromAPI in the codeunit “Graph Mgt – General Tools”. This function will search for templates that need to be applied. To not overwrite any value that was inserted with the API, it needs to know the fields that were set with the API call. Those fields will be skipped when applying the template. Not all API pages use this pattern, so you must make sure to apply the same pattern as used in the standard API page.

That’s it! Now you can use your new custom fields with an API that is based on the original API. Of course this also works for any standard fields that you are missing in the API.

Next part will be about extending the sales order and sales line API. That’s going to be fun.

Comment List
Related
Recommended