github.com/prebid/prebid-server/v2@v2.18.0/docs/developers/stored-requests.md (about)

     1  # Stored Requests
     2  
     3  See https://docs.prebid.org/prebid-server/features/pbs-storedreqs.html
     4  
     5  This document gives a technical overview of the Stored Requests feature in PBS-Go.
     6  
     7  Docs outlining the motivation and uses will be added sometime in the future.
     8  
     9  ## Quickstart
    10  
    11  Configure your server to read stored requests from the filesystem:
    12  
    13  ```yaml
    14  stored_requests:
    15    filesystem: true
    16  ```
    17  
    18  Choose an ID to reference your stored request data. Throughout this doc, replace {id} with the ID you've chosen.
    19  
    20  Add the file `stored_requests/data/by_id/stored_imps/{id}.json` and populate it with some [Imp](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=17) data.
    21  
    22  ```json
    23  {
    24    "id": "test-imp-id",
    25    "banner": {
    26      "format": [
    27        {
    28          "w": 300,
    29          "h": 250
    30        },
    31        {
    32          "w": 300,
    33          "h": 600
    34        }
    35      ]
    36    },
    37    "ext": {
    38      "appnexus": {
    39        "placementId": 12883451
    40      }
    41    }
    42  }
    43  ```
    44  
    45  Start your server.
    46  
    47  ```bash
    48  go build .
    49  ./prebid-server
    50  ```
    51  
    52  And then `POST` to [`/openrtb2/auction`](../endpoints/openrtb2/auction.md) with your chosen ID.
    53  
    54  ```json
    55  {
    56    "id": "test-request-id",
    57    "imp": [
    58      {
    59        "ext": {
    60          "prebid": {
    61            "storedrequest": {
    62              "id": "{id}"
    63            }
    64          }
    65        }
    66      }
    67    ]
    68  }
    69  ```
    70  
    71  The auction will occur as if the HTTP request had included the content from `stored_requests/data/by_id/stored_imps/{id}.json` instead.
    72  
    73  ## Partially Stored Requests
    74  
    75  You can also store _part_ of the Imp on the server. For example:
    76  
    77  ```json
    78  {
    79    "banner": {
    80      "format": [
    81        {
    82          "w": 300,
    83          "h": 250
    84        },
    85        {
    86          "w": 300,
    87          "h": 600
    88        }
    89      ]
    90    },
    91    "ext": {
    92      "appnexus": {
    93        "placementId": 12883451
    94      }
    95    }
    96  }
    97  ```
    98  
    99  This is not _fully_ legal OpenRTB `imp` data, since it lacks an `id`.
   100  
   101  However, incoming HTTP requests can fill in the missing data to complete the OpenRTB request:
   102  
   103  ```json
   104  {
   105    "id": "test-request-id",
   106    "imp": [
   107      {
   108        "id": "test-imp-id",
   109        "ext": {
   110          "prebid": {
   111            "storedrequest": {
   112              "id": "{id}"
   113            }
   114          }
   115        }
   116      }
   117    ]
   118  }
   119  ```
   120  
   121  If the Stored Request and the HTTP request have conflicting properties,
   122  they will be resolved with a [JSON Merge Patch](https://tools.ietf.org/html/rfc7386).
   123  HTTP request properties will overwrite the Stored Request ones.
   124  
   125  ## Stored BidRequests
   126  
   127  So far, our examples have only used Stored Imp data. However, Stored Requests
   128  are also allowed on the [BidRequest](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=15).
   129  These work exactly the same way, but support storing properties like timeouts and price granularity.
   130  
   131  For example, assume the following `stored_requests/data/by_id/stored_requests/stored-request.json`:
   132  
   133  ```json
   134  {
   135      "tmax": 1000,
   136      "ext": {
   137        "prebid": {
   138          "targeting": {
   139            "pricegranularity": "low",
   140          }
   141        }
   142      }
   143    }
   144  ```
   145  
   146  Then an HTTP request like:
   147  
   148  ```json
   149  {
   150    "id": "test-request-id",
   151    "imp": [
   152      "Any valid Imp data in here"
   153    ],
   154    "ext": {
   155      "prebid": {
   156        "storedrequest": {
   157          "id": "stored-request"
   158        }
   159      }
   160    }
   161  }
   162  ```
   163  
   164  will produce the same auction as if the HTTP request had been:
   165  
   166  ```json
   167  {
   168    "id": "test-request-id",
   169    "tmax": 1000,
   170    "imp": [
   171      "Any valid Imp data in here"
   172    ],
   173    "ext": {
   174      "prebid": {
   175        "targeting": {
   176          "pricegranularity": "low",
   177        }
   178      }
   179    }
   180  }
   181  ```
   182  
   183  Prebid Server does allow Stored BidRequests and Stored Imps in the same HTTP Request.
   184  The Stored BidRequest patch will be applied first, and then the Stored Imp patches after.
   185  
   186  **Beware**: Stored Request data will not be applied recursively.
   187  If a Stored BidRequest includes Imps with their own Stored Request IDs,
   188  then the data for those Stored Imps not be resolved.
   189  
   190  ## Alternate backends
   191  
   192  Stored Requests do not need to be saved to files. [Other backends](../../stored_requests/backends) are supported
   193  with different [configuration options](configuration.md). For example:
   194  
   195  ```yaml
   196  stored_requests:
   197    database:
   198      connection:
   199        driver: postgres
   200        host: localhost
   201        port: 5432
   202        user: db-username
   203        dbname: database-name
   204      fetcher:
   205        query: SELECT id, requestData, 'request' as type FROM stored_requests WHERE id in $REQUEST_ID_LIST UNION ALL SELECT id, impData, 'imp' as type FROM stored_imps WHERE id in $IMP_ID_LIST;
   206  ```
   207  
   208  ### Supported Databases
   209  - postgres
   210  - mysql
   211  
   212  ### Query Syntax
   213  All database queries should be expressed using the native SQL syntax of your supported database of choice with one caveat.
   214  
   215  For all supported database drivers, wherever you need to specify a query parameter, you must not use the native syntax (e.g. `$1`, `%%`, `?`, etc.), but rather a PBS-specific syntax to represent the parameter which is of the format `$VARIABLE_NAME`. PBS currently supports just four query parameters, each of which pertains to particular config queries, and here is how they should be specified in your queries:
   216  - last updated at timestamp --> `$LAST_UPDATED`
   217  - stored request ID list --> `$REQUEST_ID_LIST`
   218  - stored imp ID list --> `$IMP_ID_LIST`
   219  - stored response ID list --> `$ID_LIST`
   220  
   221  See the query defined at `stored_requests.database.connection.fetcher.query` in the yaml config above as an example of how to mix these variables in with native SQL syntax.
   222  
   223  ```yaml
   224  stored_requests:
   225    http:
   226      endpoint: http://stored-requests.prebid.com
   227      amp_endpoint: http://stored-requests.prebid.com?amp=true
   228  
   229  ```
   230  
   231  If you need support for a backend that you don't see, please [contribute it](contributing.md).
   232  
   233  ## Caches and Event-based updating
   234  
   235  Stored Request data can also be cached or updated while PBS is running.
   236  Conceptually, Stored Request data is managed by three separate interfaces in the code:
   237  
   238  **Fetcher**: These pull data directly from a backend.
   239  **Cache**: Duplicates data which the Fetcher _could_ find so that it can be accessed more quickly.
   240  **EventProducer**: Returns some Channels which can be used to signal changes to Stored Request data.
   241  
   242  Fetchers, Caches, and EventProducers can also be chosen in the the app config.
   243  At least one Fetcher is _required_ to make use of Stored Requests.
   244  
   245  If more than one Fetcher is defined, they will be ordered and used as fallback data sources.
   246  This isn't a great idea for Prod in the long-term, but may be useful temporarily if you're trying
   247  to transition from one backend to another.
   248  
   249  If more than one Cache is defined, they will be composed into a single Cache. Saves will propagate to all Cache layers.
   250  Any concrete Fetcher in the project will be composed with any Cache(s) to create a new Fetcher.
   251  
   252  EventProducer events are used to Save or Invalidate values from the Cache(s).
   253  Saves and invalidates will propagate to all Cache layers.
   254  
   255  Here is an example `pbs.yaml` file which looks for Stored Requests first from Database (i.e. Postgres), and then from an HTTP endpoint.
   256  It will use an in-memory LRU cache to store data locally, and poll another HTTP endpoint to listen for updates.
   257  
   258  ```yaml
   259  stored_requests:
   260    database:
   261      connection:
   262        driver: postgres
   263        host: localhost
   264        port: 5432
   265        user: db-username
   266        dbname: database-name
   267      fetcher:
   268        query: SELECT id, requestData, 'request' as type FROM stored_requests WHERE id in $REQUEST_ID_LIST UNION ALL SELECT id, impData, 'imp' as type FROM stored_imps WHERE id in $IMP_ID_LIST;
   269    http:
   270      endpoint: http://stored-requests.prebid.com
   271      amp_endpoint: http://stored-requests.prebid.com?amp=true
   272    in_memory_cache:
   273      ttl_seconds: 300 # 5 minutes
   274      request_cache_size_bytes: 107374182 # 0.1GB
   275      imp_cache_size_bytes: 107374182 # 0.1GB
   276    http_events:
   277      endpoint: http://stored-requests.prebid.com
   278      amp_endpoint: http://stored-requests.prebid.com?amp=true
   279      refresh_rate_seconds: 60
   280      timeout_ms: 100
   281  ```
   282  
   283  Pull Requests for new Fetchers, Caches, or EventProducers are always welcome.