0010: Targeted API Architecture
STATUS
Approved
CONTEXT
AdAction wants to offer a product that serves single- and multi-reward targeted offers to app users. This API should consume the Offer API while providing additional player-specific filtering. This API should also be designed in so that it can be dogfooded by the AdGem Offerwall UI (https://adunits.adgem.com/wall).
PHASE 1
This phase will implement minimal filtering in the form of location and device. Player data should be obtained through client/browser hints with user-agent parsing as the default.
This iteration will serve apps that need minimal player-based filtering. For example, the innovation team projects.
PHASE 2
This phase will implement device and os filtering, as well as conversion history filters through adgem/ad-tracking (i.e., filter out previously converted offers and offers whose limits the player has exceeded).
This iteration will allow the AdGem Offerwall UI to dogfood this API, and allow apps designated for beta to integrate this API.
PHASE 3
This phase will implement support for sorting algorithms, allowing pubs to specify sort order.
This iteration will enhance the integrations of the AdGem Offerwall UI and apps in beta.
Filtering vs Targeting
Because of the relationship between the Targeted API and the Offer API, and for the sake of clarity, the differences between targeting and filtering should be articulated.
Within the context of AdGem, targeting can be defined as, "selecting offers based on what we know about the client." The way that we get to know the client is through HTTP client hints or the user-agent.
On the other hand, filtering is defined as, "retrieving offers based on explicit/declaritive fields provided by the client." This happens when a client passes valid key-value pairs (e.g., a query string parameter).
The Offer API is built to use filtering as its selection method.
The Targeted API, however, will predominantly harness targeting as its selection method, though the publisher can include filtering in the request. Once the Targeted API has gathered information about the player, some of this data will be included in the Offer API request as filters. For example, if a client hint indicates that the player is located in France, the Targeted API will include country_codes=FR in its request to the Offer API.
Considered Options for Phase 1
- Integrate into Offer API Service
- Separate Targeted API Service - DECISION
Option 1: Integrate into Offer API Service
Description
Integrating the Targeted API into the existing Offer API involves adding routes, controllers, and filtering (maybe new service and repository) layers to the adgem/offer-api codebase.
Data Flow
Pros
- Minimal (if any) infrastructure work.
- Minimal increase in DevOps work.
- The integration would benefit from existing optimizations to the Offer API.
Cons
- Coding decisions might impact both the Offer and Targeted APIs.
- One service would need to meet the different scaling needs of the two APIs (i.e., the Targeted API is player-facing and the Offer API is publisher-facing).
- Running both services on the same infrastructure doesn't allow us to optimize the infrastructure for either as it needs to support both.
- The performance of one API may impact the other due to the shared resources.
Service Level Agreements
- Availability: 99.9% uptime
- Response time: p95 for 800ms
- Throughput: 400/minute
- Error rate: 1% over 30 days
Option 2: Separate Targeted API Service
Description
Standing up a dedicated Targeted API service involves upfront infrastructure work; routing, controller, and filtering layers; and an Offer API client.
Data Flow
Pros
- We can apply what we've learned from the Offer API configuration.
- Coding decisions impact the Targeted API only.
- Each service would be able to meet the different scaling needs of the two APIs (i.e., the Targeted API is player-facing and the Offer API is publisher-facing).
- Running separate services allows us to optimize the infrastructure for both APIs.
- Neither service impacts the performance of the other.
Cons
- Requires infrastructure work.
- Creates new service to maintain, resulting in increased in DevOps work.
- Requires creating authentication logic.
- The service would not benefit from existing optimizations to the Offer API.
- Potential latency introduced with additional service-to-service request
Service Level Agreements
- Availability: 99.9% uptime
- Response time: p95 for 800ms
- Throughput: 400/minute
- Error rate: 1% over 30 days
DECISION
Choosing with option 2 (separate Targeted API service) would result in the ability to optimize each service to meet the needs of its clients.
Choosing option 2 also gives us an opportunity to test our templatized platform components.
CONSEQUENCES
To execute option 2, a new service needs to be created. Also, the offers housed in the existing Offer API service need to be made available to the Targeted API.
Risks
If the templatized elements aren't initially successful, we potentially add time on the front-end for debugging.
NOTES
References
- PR #41: docs(AGPI-1082): creates draft of Targeted API Architecture adr
- PR #68: fix: Flatten indexes of docs to prep for auto-index merge
- PR #127: docs: backfill PR reference links for existing ADRs
Original Author
Micah Wierenga