Seller App is a native mobile application that provides all features necessary for sellers worldwide to onboard, sell products and manage their business using the app. As it is used by multiple teams in Amazon to deliver their features, it was essential for the platform to manage, standardise and provide a low latency solution for content creation in the app without having to code separately for multiple platforms which is why SellerApp platform team came up with customised framework called native framework.
SellerApp’s native UI framework
SellerApp’s native framework allows developers to dynamically create native content based off of JSON models which can be provided server side from any number of endpoints owned by different teams. It acts as a wrapper over native Android/iOS libraries and comes with a set of pre defined components and commands with a specific behaviour that understand how to read the server side rendered JSON and create native component out of it. The architecture for this follows the MVP(Model-View-Presenter) structure where certain tasks are delegated to certain classes. This makes it easier to separate out the logic between business, view updates and the actual data. A number of extensible native classes are available as part of the framework to get some basic functionality across all of our components.
At backend, it creates low-level models of interface elements and sends the information over a normal HTTP response, which native apps de-serialize and turn into native components. Builders are provided which can be used by clients to create the layout interface. The framework is server side rendered, so separate endpoints for mobile pages are needed that compose and return the views/data as JSON response. All screens in the app are being constructed from web URLs which use builders and send JSON back to the app describing the interface, the app then turns that into native components.
This makes it possible for developers to create native content without having development knowledge of Android and IOS and provide better look and feel, faster performance and interaction to the end user.
Even though this solution made native content development in SellerApp easy, it came with its own set of problems. First of it being the complexity, most of the devs are familiar with web development and it was difficult for them to understand the framework, how it works, and what clients are supposed to do to integrate with it. The following up of documentation, repeated build and deploy to test minute UI changes added to developmental tasks and increased the overall development efforts. Second problem was that the product teams were not able to create app content without being dependent on developers. Third major problem was the need for clients to add the framework as a dependency on their application. This increased maintenance load due to occasional migration, etc tasks.
There are lot of pages that are targeted to be created in seller app from time to time. And the process of creating any help content page required SDE effort of writing the code, setting up stack/infrastructure and endpoints. This all requires weeks of effort and adds the maintenance effort for the infra setup. There was no possibility of creating a new page from an earlier launched page that could have reduced the time to launch a new page. Thus it was absolutely necessary to create a solution to create a no code/low code SellerApp UI creation platform.
To solve the issue, our team created a platform that came with a WYSIWYG editor that would allow creating/managing such native app pages without any code setup with user friendly GUI to bring down the effort to couple of hours of effort and preview. This reduced the efforts significantly and made the process of creating help content pages easier.
The platform comes with an uber vision to make it possible to support creation of any kind of native pages for SellerApp. This will enable teams to create the pages across platforms and make sure the mobile-first requirement is met, at the same time not having to allocate extra resource to manage multiple stacks.
We initially launched the support creating static content pages via the editor which will provide options to add different components and set the required attributes on each of the components. The pages created by this portal will then be stored in backend and using the pageId, the team could render the content in app. The rendering will be done in the native Android/iOS using native framework. The tool will also support the updating of the pages already created, and the pipeline will take care of propagating the changes automatically.
We created an internal portal integrated with our backend, which would be used by product and tech teams alike to create and manage the SellerApp pages. Support was provided to mention the components required by the page, attributes of individual components a drag and drop interface and a WYSIWYG editor to view the final page. The page could then be saved and tested, and was ready to be rendered in SellerApp.
The APIs handle the CRUD (Create, Read, Update, Delete) operations triggered from the internal portal. The backend saves the meta data store and the complete JSON of the page in S3, with version control. This way the page layout and data is saved to s3 along with metadata store in DynamoDB. A unique id is associated with each page, that will be used to access the page.
The pageId generated by the portal can be used to generate the page in Seller App. Once a render request is made, application backend validates the request and fetches the required components information from S3. Based on the component data and attribute information, individual component classes were triggered which were integrated with native framework builders to generate the required content. Exposing this functionality as a service made it possible for us to make all our clients independent on native framework dependencies.
While we solved the problem of page creation by storing the page’s metadata and using that at runtime to generate the SellerApp pages, its scope was limited. The tool in that state could only be used to create static pages showing fixed content irrespective of user’s context. To address for scenarios where the data is dynamic, it was required to integrate with storage systems where data is uploaded and for fetching data through API integration.
This phase supported creating the pages which get the content from supported backend APIs. This was done by allowing the user to add data source as an attribute value instead of actual data. The internal client teams, consisting of product and tech teams, use the internal portal to create the page layout. The page will consist of different components some of which will be static and other might have dynamic values. The portal will allow denoting the components accordingly, so user can put in actual values for static components and placeholders for dynamic values to be filled at runtime. The rendering stack will take care of making the appropriate calls and fetching the data and populating the components before rendering the same in the native Android/iOS using native framework. As before, the tool will also support the updating of the pages already created, and the pipeline will take care of propagating the changes automatically.
For every page that is served by our platform, we are fetching page layout, dynamic Id values from Amazon S3. Also, we fetch the page metadata from Amazon DynamoDB. To solve this problem of repeated fetching from S3 or DynamoDB, we implemented caching for both content being fetched from DDB and S3.
This approach uses
- Amazon CloudFront to cache S3 Content Pages.
- DynamoDB Accelerator (DAX) as a cache for DynamoDB PageMeta data
We switched from fetching page content directly from S3 to CloudFront URL.
- If the page content Data is present in the CloudFront cache, it will be returned from the edge location (a worldwide network of data centers) nearest to the user.
- Otherwise, Cloudfront will redirect the request to the Amazon S3 location, and cache the content for the next time this request is made, before returning response to the client.
DAX or DynamoDB Accelerator was used for the PageMetaData Table.DAX or DynamoDB Accelerator is a fully managed, highly available, in-memory cache for DynamoDB.
We will be accessing data from it in a read through manner.
- If it is a cache HIT, data will be fetched from the DAX Cache.
- If it is a cache miss, it gets the data from DynamoDB, and caches it for the next requests
With the increasing adoption of this product among multiple teams, it was necessary to do proper multi page management. If every created page was maintained under 1 group., it could have led to mismanagement, and accidental updations to page’s not belonging to a certain team. We created a permissions system where one can create a permission group for a particular set of pages, which will have view and edit permission model. These groups once registered, will be owned by the respective team and the pages created will have the group associated with it. This would allow only the people within certain access group to visit and edit their pages. User can request to add a permission group with view, edit and publish permissions, which will be related to that particular team/group and pages will be associated with it.
To add an additional step of security so that accidental creation/updation of pages would not directly impact end user, we added an approval workflow on our tool. Every create/update page request needed to be followed up with an approval request, which would trigger an approval workflow and notify the admins of a particular permission group. The admins can then view the page, and approve it, only after which it would be visible to external users.
Future scope includes auto-suggestion and first look creation of the pages based on the client teams’ use-cases. The existing solution will be extended to support categorisation of the the UI pages.