1 min read

Custom Sub service customisation example

In case of Sub service customisation we only modify and inject a small piece of Mid Level service logic.

Let us imagine that our client has a required custom field defined for its Customer object for example c_customField of type string that we need to be able to read and update. User story can look like this: As a User I want to be able to manipulate c_customField on Register and Edit Account screens. In order to implement this solution we are going to provide our own implementation of ISfccCustomerConverter service that will hold required mapping. Implementation plan will be as follows:

  1. Create custom ISfccCustomerConverter implementation
  2. Bootstrap code by copy pasting standard ISfccCustomerConverter implementation code from SDK library
  3. Map SF c_customField from ProfileRequest.CustomData.CustomField
  4. Map SF c_customField to ProfileResponse.CustomData.CustomField

Let us proceed to the implementation.

Prerequisites

  • Sfcc Based BFC API up and running locally

Steps

  1. Go to Poq.Api.Yourbrand.Service project
  2. Go to Account/Models folder and create new class YourBrandCustomer that inherits SfccCustomer model and has c_customField in it
using Newtonsoft.Json;
using Poq.Sfcc.Client.Contract.Customer;
namespace Poq.Api.YourBrand.Service.Account.Models
{
public class YourBrandCustomer : SfccCustomer
{
[JsonProperty("c_customField")]
public string CustomField { get; set; }
}
}
  1. Go to Account folder and create CustomSfccCustomerConverter: ISfccCustomerConverter
using Poq.Sfcc.Service.Account.Interface;
namespace Poq.Api.YourBrand.Service.Account
{
public class CustomSfccCustomerConverter : ISfccCustomerConverter
{
}
}
  1. Go to Sfcc SDK source code and copy paste base implementation of ISfccCustomerConverter into CustomSfccCustomerConverter
If you do not have access to SDK sources please reach out to your Poq contact.
using Newtonsoft.Json.Linq;
using Poq.Contract.Account;
using Poq.Sfcc.Client.Contract.Customer;
using Poq.Sfcc.Service.Account.Interface;
namespace Poq.Api.YourBrand.Service.Account
{
public class CustomSfccCustomerConverter : ISfccCustomerConverter
{
public ProfileResponse ToProfileResponse<TSfccCustomer>(TSfccCustomer customer) where TSfccCustomer : SfccCustomer
{
return new ProfileResponse()
{
Email = customer.Email,
FirstName = customer.FirstName,
LastName = customer.LastName,
Phone = customer.PhoneHome,
CustomData = JObject.FromObject(new
{
accountId = customer.CustomerId,
username = customer.Login,
title = customer.Title
})
};
}
public TSfccCustomer ToSfccCustomer<TSfccCustomer>(ProfileRequest profileRequest, string? customerId = null) where TSfccCustomer : SfccCustomer, new()
{
return new TSfccCustomer()
{
CustomerId = customerId!,
Email = profileRequest.Email!,
Login = profileRequest.Email!,
FirstName = profileRequest.FirstName!,
LastName = profileRequest.LastName!,
PhoneHome = profileRequest.Phone,
Title = (profileRequest.CustomData as JObject)?.GetValue("title")?.Value<string>(),
};
}
}
}
  1. Add mapping of custom field to ToSfccCustomer method to handle c_customField updates
public TSfccCustomer ToSfccCustomer<TSfccCustomer>(ProfileRequest profileRequest, string? customerId = null) where TSfccCustomer : SfccCustomer, new()
{
var sfccCustomer = new TSfccCustomer()
{
CustomerId = customerId!,
Email = profileRequest.Email!,
Login = profileRequest.Email!,
FirstName = profileRequest.FirstName!,
LastName = profileRequest.LastName!,
PhoneHome = profileRequest.Phone,
Title = (profileRequest.CustomData as JObject)?.GetValue("title")?.Value<string>(),
};
if (sfccCustomer is YourBrandCustomer yourBrandCustomer)
{
yourBrandCustomer.CustomField = (profileRequest.CustomData as JObject)?.GetValue("customField")?.Value<string>()!;
}
return sfccCustomer;
}
  1. Add mapping of custom field to ToProfileResponse method to handle c_customField read
public ProfileResponse ToProfileResponse<TSfccCustomer>(TSfccCustomer customer) where TSfccCustomer : SfccCustomer
{
if (customer is not YourBrandCustomer yourBrandCustomer)
throw new ArgumentException($"Expected {nameof(TSfccCustomer)} type is {typeof(YourBrandCustomer)}");
return new ProfileResponse()
{
Email = yourBrandCustomer.Email,
FirstName = yourBrandCustomer.FirstName,
LastName = yourBrandCustomer.LastName,
Phone = yourBrandCustomer.PhoneHome,
CustomData = JObject.FromObject(new
{
accountId = yourBrandCustomer.CustomerId,
username = yourBrandCustomer.Login,
title = yourBrandCustomer.Title,
customField = yourBrandCustomer.CustomField
})
};
}
  1. Register CustomSfccCustomerConverter in ServiceCollection
services.AddScoped<ISfccCustomerConverter, CustomSfccCustomerConverter>();
  1. Test /account/register and /account/profile endpoints to make sure that custom field is being get and set properly
  2. Add unit tests. You bootstrap unit tests from Sfcc SDK source code as well.
  3. Submit the PR
Congratulations, you have successfully implemented Mid level customisation.

See Next