Post Example

In the previous section, we learned how to leverage the self.request_parameters attribute to retrieve query and body parameters from the request. However, this is one of many functionalities at your disposal. In this section, we will update an end-user’s account nickname which will allow us to explore the full capabilities of the SDK custom endpoint extension.

Initial Setup

First, we will want to grab the necessary imports:

from q2_sdk.hq.hq_api.q2_api import ChangeEndUserAccountNickname
from q2_sdk.hq.models.db_config.db_config import DbConfig
from q2_sdk.hq.models.db_config.db_config_list import DbConfigList

Be sure to add these at the top of the extension.py file.

Since our objective is to update account nicknames, let’s first register a nickname prefix to the database. This will help categorize the user’s accounts:

WEDGE_ADDRESS_CONFIGS = DbConfigList(
    [
        DbConfig("NickNamePrefix", "API Set: "),
    ]
)

Once the extension is installed, the NickNamePrefix will be registered as a wedge configuration and will automatically be accessible through the self.wedge_address_configs attribute.

In order to update account nicknames, we will also need to retrieve certain bits of information from our request. Let’s define them as required parameters:

REQUIRED_PARAMETERS = ["LoginName", "HostAccountID", "RequestedNickName"]

Retrieving Required Values

Before proceeding, let’s ensure we have access to these values so that they are readily available when we make our request from the API. Feel free to use your login from the Online Banking Form tutorial. Otherwise, you can create a new one via the q2 create_online_user command.

Next, we will need the host account id of the user’s account. Please move on to the next section if you have one handy. Otherwise, a new account can be created via the q2 add_new_account CLI command. Once run, you will be prompted to fill out various account details and will be provided with a host account id:

$ q2 add_new_account
    ...
    New Account created with ID: 1234

Continue to follow the prompts until you are asked to link the account to a login. Make sure to select Y and provide your login name. In this example tutorial, we will be using retail0:

$ q2 add_new_account
    ...
    Account populated with HADEs
    Do you want to link this account now? [Y/n] Y
    What login do you want to link this account to?: retail0

At this step, you should have a login name and host account id. The RequestedNickName parameter will be provided at request time. Now that we have all of the pieces we need to update account nicknames, we are ready to move on to the next section.

Overriding the Post Function

In this section, we will break down the logic for the post() method. This method will take in our required parameters from the request payload, perform some validation on these, and attempt to update the account nickname using the host account ID. Let’s explore the code:

    async def post(self):
        self.set_header("Content-Type", "application/json")

        if not self.request_parameters:
            errors = [{"code": 400, "message": "No request body"}]
            to_return = self.return_data({}, success=False, errors=errors)
            self.write(to_return)
            return

        missing_parameters = [x for x in self.REQUIRED_PARAMETERS
                              if x not in self.request_parameters.keys()]
        if missing_parameters:
            errors = [{ "code": 400, "message": f"missing required parameters: {missing_parameters}"}]
            to_return = self.return_data({}, success=False, errors=errors)
            self.write(to_return)
            return
        ...

Once again, we set our headers to applications/json. We attempt to retrieve all of the required parameters from the incoming request. If no parameters are provided, or a parameter is missing, we utilize the self.return_data function to return an error message and error code containing more details regarding the failure.

Notice, if you were to navigate through the various endpoints within the API documentation, the parameters in return_data mirror the fields from the response payload of each endpoint:

../../_images/api_response.png

A data, success, and errors field will always be added as part of the response. We typically include an error code and message within the errors section to detail the failures. As a best practice, we recommend that you provide a generic error message and log out additional details via the self.logger property to avoid leaking any sensitive information. The remaining fields in the response, including the requestid, status, and log_ref_id are automatically populated by the API.

Now that you have a better understanding of self.return_data, let’s move on to the next portion of the code.

Congratulations, you are ready to install your extension!