From 083f4ff8f0333c64fb5bd67fe59a2e2f159db8cf Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:57:45 -0700 Subject: [PATCH 01/11] adding versioned docs infrastructure --- .travis.yml | 25 ++- .../001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md | 0 .../010 - optimizely-agent.md | 0 .../012 - quickstart-for-agent.md | 0 .../020 - setup-optimizely-agent.md | 0 .../010 - evaluate-rest-apis.md | 0 .../020 - admin-api.md | 0 .../030 - use-optimizely-agent/index.md | 0 .../010 - authorization.md | 0 .../020 - webhooks-agent.md | 0 .../030 - docker-configurations.md | 0 .../031 - agent-notifications.md | 0 .../040 - advanced-configuration.md | 0 .../050 - agent-plugins.md | 0 .../040 - configure-optimizely-agent/index.md | 0 .../050 - api-reference.md | 0 .../060 - github-repository.md | 0 .../001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md | 10 + .../010 - optimizely-agent.md | 78 ++++++++ .../012 - quickstart-for-agent.md | 88 ++++++++ .../020 - setup-optimizely-agent.md | 75 +++++++ .../010 - evaluate-rest-apis.md | 59 ++++++ .../020 - admin-api.md | 89 +++++++++ .../030 - use-optimizely-agent/index.md | 99 +++++++++ .../010 - authorization.md | 188 ++++++++++++++++++ .../020 - webhooks-agent.md | 41 ++++ .../030 - docker-configurations.md | 9 + .../031 - agent-notifications.md | 57 ++++++ .../040 - advanced-configuration.md | 56 ++++++ .../050 - agent-plugins.md | 86 ++++++++ .../040 - configure-optimizely-agent/index.md | 56 ++++++ .../050 - api-reference.md | 11 + .../060 - github-repository.md | 11 + 33 files changed, 1029 insertions(+), 9 deletions(-) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/010 - optimizely-agent.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/012 - quickstart-for-agent.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/020 - setup-optimizely-agent.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/030 - use-optimizely-agent/index.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/050 - api-reference.md (100%) rename docs/readme-sync/{ => v3.1}/deploy-as-a-microservice/060 - github-repository.md (100%) create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md create mode 100644 docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md diff --git a/.travis.yml b/.travis.yml index cc19bc0e..33365230 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,14 +15,15 @@ branches: - /^v\d+\.\d+(\.\d+)?(-\S*)?$/ stages: + - 'Readme-sync-preview' + - 'Readme-sync' - 'Tests' - 'Trigger FSC Tests' - 'Test Build using latest tag (no upload)' - 'Build, Upload and Publish (draft)' - 'Test github release assets' - 'Publish (real)' - - 'Readme-sync-preview' - - 'Readme-sync' + jobs: @@ -240,15 +241,19 @@ jobs: # we need to be in $TRAVIS_BUILD_DIR in order to run the following git diff properly - cd $TRAVIS_BUILD_DIR - #print which docs changed in this Pull Request (and which therefore we expect to be updated by readme-sync-2 tool): + # print which docs changed in this Pull Request (and which therefore we expect to be updated by readme-sync-2 tool): - CHANGED_DOCS_FILES=($(git diff --name-only $TRAVIS_COMMIT_RANGE -- docs/readme-sync)) - echo $CHANGED_DOCS_FILES - #only if changes were made in the docs/readme-sync repo, trigger this readme-sync stage and sync the docs - - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY_PREVIEW --version 4.0 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/) - + # only if changes were made in the docs/readme-sync repo, trigger this readme-sync stage and sync the docs + # to staging readme project at https://rollouts-sandbox-doc-test.readme.io/docs + # build v3.1 docs to v 1.0 of readme staging project + - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync/v3.1 || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY_PREVIEW --version 1.0 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/v3.1) + # build v4.0 docs to v 1.5 of staging project + - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync/v4.0 || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY_PREVIEW --version 1.5 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/v4.0) + - stage: 'Readme-sync' before_script: skip cache: false @@ -272,9 +277,11 @@ jobs: - CHANGED_DOCS_FILES=($(git diff --name-only $TRAVIS_COMMIT_RANGE -- docs/readme-sync)) - echo $CHANGED_DOCS_FILES - #only if changes were made in the docs/readme-sync repo, trigger this readme-sync stage and sync the docs - - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY --version 3.1 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/) - + #only if changes were made in the docs/readme-sync repo, trigger this readme-sync stage and sync the docs + # sync v3.1 docs folder to readme project v 3.1 + - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync/v3.1 || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY --version 3.1 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/v3.1 + # sync v4.0 docs folder to readme project v 4.0 + - git diff --quiet $TRAVIS_COMMIT_RANGE -- docs/readme-sync/v4.0 || ( cd $HOME/readme-sync2 && npx ts-node sync/index.ts --apiKey $README_SYNC_API_KEY --version 4.0 --docs $TRAVIS_BUILD_DIR/docs/readme-sync/v4.0 ######################################################################################### # directories/scripts for full SDK-reference-guides, to be implemented after agent docs sync ######################################################################################### diff --git a/docs/readme-sync/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md diff --git a/docs/readme-sync/deploy-as-a-microservice/010 - optimizely-agent.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/010 - optimizely-agent.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/010 - optimizely-agent.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/010 - optimizely-agent.md diff --git a/docs/readme-sync/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/012 - quickstart-for-agent.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md diff --git a/docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/020 - setup-optimizely-agent.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/020 - setup-optimizely-agent.md diff --git a/docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md diff --git a/docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md diff --git a/docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/030 - use-optimizely-agent/index.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md diff --git a/docs/readme-sync/deploy-as-a-microservice/050 - api-reference.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/050 - api-reference.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md diff --git a/docs/readme-sync/deploy-as-a-microservice/060 - github-repository.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/060 - github-repository.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/060 - github-repository.md rename to docs/readme-sync/v3.1/deploy-as-a-microservice/060 - github-repository.md diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md new file mode 100644 index 00000000..a17a19d0 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md @@ -0,0 +1,10 @@ +--- +title: "CAUTION - DON'T AUTHOR AGENT DOCS IN README" +excerpt: "" +slug: "author-agent-docs-in-github" +hidden: true +createdAt: "2020-02-21T17:44:53.019Z" +updatedAt: "2020-04-13T23:02:34.056Z" +--- + +Agent docs sync from Github. So, any changes you author here in Readme will just be overwritten. Make docs updates over in Github. For more info, see [authoring guidelines in github](https://github.com/optimizely/agent/blob/master/docs/internal%20docs%20authoring%20notes.md). diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md new file mode 100644 index 00000000..5bdadc3c --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md @@ -0,0 +1,78 @@ +--- +title: "Optimizely Agent" +excerpt: "" +slug: "optimizely-agent" +hidden: false +metadata: + title: "Optimizely Agent microservice - Optimizely Full Stack" +createdAt: "2020-02-21T20:35:58.387Z" +updatedAt: "2020-07-14T20:51:52.458Z" +--- +Optimizely Agent is a standalone, open-source, and highly available microservice that provides major benefits over using Optimizely SDKs in certain use cases. The [Agent REST API](https://library.optimizely.com/docs/api/agent/v1/index.html) offers consolidated and simplified endpoints for accessing all the functionality of Optimizely Full Stack SDKs. + +A typical production installation of Optimizely Agent is to run two or more services behind a load balancer or proxy. The service itself can be run via a Docker container or installed from source. See [Setup Optimizely Agent](doc:setup-optimizely-agent) for instructions on how to run Optimizely Agent. + +### Example Implementation +![example implementation](https://raw.githubusercontent.com/optimizely/agent/master/docs/images/agent-example-implementation.png) +# Should I Use Optimizely Agent? + +Here are some of the top reasons to consider using Optimizely Agent: + +## 1. Service Oriented Architecture (SOA) +If you already separate some of your logic into services that might need to access the Optimizely decision APIs, we recommend using Optimizely Agent. + +The images below compare implementation styles in a service-oriented architecture, first *without* using Optimizely Agent, which shows six SDK embedded instances: + +!["A diagram showing the use of SDKs installed on each service in a service oriented architecture \n(Click to Enlarge)"](https://raw.githubusercontent.com/optimizely/agent/master/docs/images/agent-service-oriented-architecture.png) + +Now *with* Agent, instead of installing the SDK six times, you create just one Optimizely instance: an HTTP API that every service can access as needed. + +!["A diagram showing the use of Optimizely Agent in a single service \n(Click to Enlarge)"](https://raw.githubusercontent.com/optimizely/agent/master/docs/images/agent-single-service.png) + +## 2. Standardize Access Across Teams +If you want to deploy Optimizely Full Stack once, then roll out the single implementation across a large number of teams, we recommend using Optimizely Agent. + +By standardizing your teams' access to the Optimizely service, you can better enforce processes and implement governance around feature management and experimentation as a practice. + +!["A diagram showing the central and standardized access to the Optimizely Agent service across an arbitrary number of teams.\n(Click to Enlarge)"](https://raw.githubusercontent.com/optimizely/agent/master/docs/images/agent-standardized-access.png) + +## 3. Networking Centralization +You don’t want many SDK instances connecting to Optimizely's cloud service from every node in your application. Optimizely Agent centralizes your network connection. Only one cluster of agent instances connects to Optimizely for tasks like update [datafiles](doc:get-the-datafile) and dispatch [events](doc:track-events). + +## 4. Languages +You’re using a language that isn’t supported by a native SDK (i.e. Elixir, Scala, Perl). While its possible to create your own service using an Optimizely SDK of your choice, you could also customize the open-source Optimizely Agent to your needs without building the service layer on your own. + + +# Reasons to *not* use Optimizely Agent +If your use case wouldn't benefit greatly from Optimizely Agent, you should consider the below reasons to *not* use Optimizely Agent and review Optimizely's many [open-source SDKs](doc:sdk-reference-guides) instead. + +## 1. Latency +If time to provide bucketing decisions is a primary concern for you, you may want to use an embedded Full Stack SDK rather than Optimizely Agent. + + +| Implementation Option | Decision Latency | +|-----------------------|------------------| +| Embedded SDK | microseconds | +| Optimizely Agent | milliseconds | + +## 2. Monolith +If your app is constructed as a monolith, embedded SDKs might be easier to install and might be a more natural fit for your application and development practices. + +## 3. Velocity +If you’re looking for the fastest way to get a single team up and running with deploying feature management and experimentation, embedding an SDK is the best option for you at first. You can always start using Optimizely Agent later, and it can even be used alongside Optimizely Full Stack SDKs running in another part of your stack. + +# Best Practices +While every implementation is different, you can review this section of best practices for tips on these commonly discussed topics. + + +## How many Agent instances should I deploy? +Agent can scale to large decision / event tracking volumes with relatively low CPU / memory specs. For example, at Optimizely, we scaled our deployment to 740 clients with a cluster of 12 agent instances, which in total use 6 vCPUs and 12GB RAM. You will likely need to focus more on network bandwidth than compute power. + +## Using a load balancer +Any standard load balancer should let you route traffic across your agent cluster. At Optimizely, we used an AWS Elastic Load Balancer (ELB) for our internal deployment. This allows us to transparently scale our agent cluster as internal demands increase. + +## Synchronizing datafiles across Agent instances +Agent offers eventual rather than strong consistency across datafiles. +In detail, today, each agent instance maintains a dedicated, separate cache. Each agent instance persists an SDK instance for each SDK key your team uses. Agent instances automatically keep datafiles up to date for each SDK key instance so that you will have eventual consistency across the cluster. The rate of the datafile update can be [set as the configuration](doc:configure-optimizely-agent) value ```OPTIMIZELY_CLIENT_POLLINGINTERVAL``` (the default is 1 minute). +Because SDKs are generally stateless today, they shouldn’t need to share data. We plan to add a common backing data store, so we invite you to share your feedback. +If you require strong consistency across datafiles, then we recommend an active / passive deployment where all requests are made to a single vertically scaled host, with a passive, standby cluster available for high availability. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md new file mode 100644 index 00000000..92a8cc16 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -0,0 +1,88 @@ +--- +title: "Quickstart for Agent" +excerpt: "" +slug: "quickstart-for-agent" +hidden: false +metadata: + title: "Quickstart for Agent - Optimizely Full Stack" +createdAt: "2020-05-21T20:35:58.387Z" +updatedAt: "2020-08-17T20:51:52.458Z" +--- + +This brief quickstart describes how to run Agent, using two examples: + +- To get started using Docker, see [Running locally via Docker](https://docs.developers.optimizely.com/full-stack/docs/quickstart-with-docker#section-running-locally-via-docker). + +- To get started using example Node microservices, see the following video link. + + + +## Running locally via Node +| Resource | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| [Implementing feature flags across microservices with Optimizely Agent](https://www.youtube.com/watch?v=kwNVdSXMGX8&t=20s) | 4-minute video on implementing Optimizely Agent with example microservices | + +## Running locally via Docker + +Follow these steps to deploy Optimizely Agent locally via Docker and access some of the common API endpoints. +If Docker is not installed then you can download it [here](https://docs.docker.com/install/). + +First pull the Docker image with: + +```bash +docker pull optimizely/agent +``` + +Then start the service in the foreground with the following command: + +```bash +docker run -p 8080:8080 --env OPTIMIZELY_LOG_PRETTY=true optimizely/agent +``` +Note that we're enabling "pretty" logs which provide colorized and human readable formatting. +The default log output format is structured JSON. + +## Evaluating REST APIs + +The rest of the getting started guide will demonstrate the APIs capabilities. For brevity, we've chosen to illustrate the API usage with Python. Note that the APIs are also defined via OpenAPI (Swagger) and can be found on localhost [here](http://localhost:8080/openapi.yaml). + +### Start an http session + +Each request made into Optimizely Agent is in the context of an Optimizely SDK Key. SDK Keys map API requests to a specific Optimizely Project and Environment. We can set up a global request header by using the `requests.Session` object. + +```python +import requests +s = requests.Session() +s.headers.update({'X-Optimizely-SDK-Key': '<>'}) +``` + +To get your SDK key, navigate to the project settings of your Optimizely account. + +Future examples will assume this session is being maintained. + +### Get current environment configuration + +The `/config` endpoint returns a manifest of the current working environment. + +```python +resp = s.get('http://localhost:8080/v1/config') +env = resp.json() + +for key in env['featuresMap']: + print(key) +``` + +### Activate Feature + +The `/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. + +From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. + +```python +params = { "featureKey": "my-feature" } +payload = { "userId": "test-user" } +resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) + +print(resp.json()) +``` + +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md new file mode 100644 index 00000000..23de9d44 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md @@ -0,0 +1,75 @@ +--- +title: "Install Optimizely Agent" +excerpt: "" +slug: "setup-optimizely-agent" +hidden: false +metadata: + title: "Install Agent - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:27.363Z" +updatedAt: "2020-03-31T23:54:17.841Z" +--- +## Running Agent from source (Linux / OSX) + +To develop and compile Optimizely Agent from source: + +1. Install [Golang](https://golang.org/dl/) version 1.13+ . +2. Clone the [Optimizely Agent repo](https://github.com/optimizely/agent). +3. From the repo directory, open a terminal and start Optimizely Agent: + +```bash +make setup +``` +Then +```bash +make run +``` + +This starts the Optimizely Agent with the default configuration in the foreground. + +## Running Agent from source (Windows) + +You can use a [helper script](https://github.com/optimizely/agent/blob/master/scripts/build.ps1) to install prerequisites (Golang, Git) and compile agent in a Windows environment. Take these steps: + +1. Clone the [Optimizely Agent repo](https://github.com/optimizely/agent) +2. From the repo directory, open a Powershell terminal and run + +```bash +Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser + +.\scripts\build.ps1 + +.\bin\optimizely.exe +``` + +## Running Agent via Docker + +If you have Docker installed, you can start Optimizely Agent as a container. Take these steps: + +1. Pull the Docker image: + +```bash +docker pull optimizely/agent +``` +By default this will pull the "latest" tag. You can also specify a specific version of Agent by providing the version as a tag to the docker command: + +```bash +docker pull optimizely/agent:X.Y.Z +``` + +2. Run the docker container with: + +```bash +docker run -p 8080:8080 optimizely/agent +``` +This will start Agent in the foreground and expose the container API port 8080 to the host. + +3. (Optional) You can alter the configuration by passing in environment variables to the preceding command, without having to create a config.yaml file. See [configure optimizely agent](doc:configure-optimizely-agent) for more options. + +Versioning: +When a new version is released, 2 images are pushed to dockerhub. They are distinguished by their tags: +- :latest (same as :X.Y.Z) +- :alpine (same as :X.Y.Z-alpine) + +The difference between latest and alpine is that latest is built `FROM scratch` while alpine is `FROM alpine`. +- [latest Dockerfile](https://github.com/optimizely/agent/blob/master/scripts/dockerfiles/Dockerfile.static) +- [alpine Dockerfile](https://github.com/optimizely/agent/blob/master/scripts/dockerfiles/Dockerfile.alpine) \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md new file mode 100644 index 00000000..e06bd6be --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -0,0 +1,59 @@ +--- +title: "Evaluate REST APIs" +excerpt: "" +slug: "evaluate-rest-apis" +hidden: false +metadata: + title: "Evaluate REST APIs - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:53.019Z" +updatedAt: "2020-04-13T23:02:34.056Z" +--- +Below is an example demonstrating the APIs capabilities. For brevity, we've chosen to illustrate the API usage with Python. Note that the API documentation is defined via an OpenAPI (Swagger) spec and can be viewed [here](https://library.optimizely.com/docs/api/agent/v1/index.htm). + +## Start an http session +Each request made into Optimizely Agent is in the context of an Optimizely SDK Key. SDK Keys map API requests to a specific Optimizely Project and Environment. We can setup a global request header by using the `requests.Session` object. + + +```python +import requests + +s = requests.Session() +s.headers.update({'X-Optimizely-SDK-Key': 'YOUR-SDK-KEY'}) +``` +The following examples will assume this session is being maintained. + +## Get current environment configuration +The `/v1/config` endpoint returns a manifest of the current working environment. + +```python +resp = s.get('http://localhost:8080/v1/config') +env = resp.json() + +for key in env['featuresMap']: + print(key) +``` + +## Activate Feature +The `/v1/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. + +From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. + + +```python +# single feature activate +params = { "featureKey": "my-feature" } +payload = { "userId": "test-user" } +resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) + +print(resp.json()) + + +# multiple (bulk) feature activate +params = { + "featureKey": [key for key in env['featuresMap']], + "experimentKey": [key for key in env['experimentsMap']] +} +resp2 = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +print(json.dumps(resp.json(), indent=4, sort_keys=True)) +``` +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md new file mode 100644 index 00000000..9aefdfba --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md @@ -0,0 +1,89 @@ +--- +title: "Admin API" +excerpt: "" +slug: "admin-api" +hidden: false +metadata: + title: "Admin APIs - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:28.054Z" +updatedAt: "2020-02-21T23:09:19.274Z" +--- +The Admin API provides system information about the running process. This can be used to check the availability of the service, runtime information and operational metrics. By default the admin listener is configured on port 8088. + +## Info + +The `/info` endpoint provides basic information about the Optimizely Agent instance. + +Example Request: +```bash +curl localhost:8088/info +``` + +Example Response: +```json +{ + "version": "v0.10.0", + "author": "Optimizely Inc.", + "app_name": "optimizely" +} +``` + +## Health Check + +The `/health` endpoint is used to determine service availability. + +Example Request: +```bash +curl localhost:8088/health +``` + +Example Response: +```json +{ + "status": "ok" +} +``` + +Agent will return a HTTP 200 - OK response if and only if all configured listeners are open and all external dependent services can be reached. +A non-healthy service will return a HTTP 503 - Unavailable response with a descriptive message to help diagnose the issue. + +This endpoint can used when placing Agent behind a load balancer to indicate whether a particular instance can receive inbound requests. + +## Metrics + +The `/metrics` endpoint exposes telemetry data of the running Optimizely Agent. The core runtime metrics are exposed via the go expvar package. Documentation for the various statistics can be found as part of the [mstats](https://golang.org/src/runtime/mstats.go) package. + +Example Request: +```bash +curl localhost:8088/metrics +``` + +Example Response: +```json +{ + "cmdline": [ + "bin/optimizely" + ], + "memstats": { + "Alloc": 924136, + "TotalAlloc": 924136, + "Sys": 71893240, + "Lookups": 0, + "Mallocs": 4726, + "HeapAlloc": 924136, + ... + "Frees": 172 + }, + ... +} +``` +Custom metrics are also provided for the individual service endpoints and follow the pattern of: + +```bash +"timers..counts": 0, +"timers..responseTime": 0, +"timers..responseTimeHist.p50": 0, +"timers..responseTimeHist.p90": 0, +"timers..responseTimeHist.p95": 0, +"timers..responseTimeHist.p99": 0, +``` \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md new file mode 100644 index 00000000..38c06368 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -0,0 +1,99 @@ +--- +title: "Use Optimizely Agent" +excerpt: "" +slug: "use-optimizely-agent" +hidden: false +metadata: + title: "How to use Optimizely Agent - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:28.054Z" +updatedAt: "2020-04-08T21:26:30.308Z" +--- + +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. + +### Manage features + + Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: + +- [isFeatureEnabled](doc:is-feature-enabled-go) +- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) +- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) +- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) +- [getFeatureVariableString](doc:get-feature-variable-go#section-string) +- [getEnabledFeatures](doc:get-enabled-features-go) + + +... into one, convenient endpoint: + +`POST /v1/activate?featureKey={featureKey}` + +This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: + +- the decision for this feature for this user +- any corresponding feature variable values. + +For example: + +```json +{ + "featureKey": "feature-key-1", + "enabled": true, + "variables": { + "my-var-1": "cust-val-1", + "my-var-2": "cust-va1-2" + } +} +``` + +The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. + +Note: If the user is assigned to a feature test, this API will dispatch an impression. + +### Authentication + + +To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. + + +### Running A/B tests + + +To activate an A/B test, use: + +`POST /v1/activate?experimentKey={experimentKey}` + +This dispatches an impression and return the user’s assigned variation: + +`POST /v1/activate?experimentKey={experimentKey}` + +This dispatches an impression and return the user’s assigned variation: +```json +{ + "experimentKey": "experiment-key-1", + "variationKey": "variation-key-1" +} +``` +### Get All Decisions +To get all Feature decisions for a visitor in a single request use: +`POST /v1/activate?type=feature` + +To receive only the enabled features for a visitor use: + +`POST /v1/activate?type=feature&enabled=true` + +To get all Experiment decisions for a visitor in a single request use: +`POST /v1/activate?type=experiment` + + + +### Tracking conversions + +To track events, use the same [tracking endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/trackEvent) you use in the [SDKs' track API](doc:track-javascript): + +`POST /v1/track?eventKey={eventKey}` + +There is no response body for successful conversion event requests. + +### API reference + + For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md new file mode 100644 index 00000000..df731365 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md @@ -0,0 +1,188 @@ +--- +title: "Authorization" +excerpt: "" +slug: "authorization" +hidden: false +metadata: + title: "Agent Authorization - Optimizely Full Stack" +createdAt: "2020-03-11T20:58:11.777Z" +updatedAt: "2020-03-31T19:44:52.119Z" +--- +Optimizely Agent supports authorization workflows based on OAuth and JWT standards, allowing you to protect access to its API and Admin interfaces. + +There are three modes of operation: + +## 1. Issuer & Validator +Access tokens are issued by Agent itself, using a [Client Credentials grant](https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/). Access tokens are signed and validated using the HS256 algorithm with a signing secret provided in configuration. Clients request access tokens by sending a `POST` request to `/oauth/token` on the port of the desired interface (by default, `8080` for the API interface, and `8088` for the Admin interface), including a client ID and secret in the request. + + +Issuer & Validator mode is useful if you want to implement authorization, and you are not already running an authorization server that can issue JWTs. + +## 2. Validator-only +Agent validates access tokens that were issued elsewhere. Access tokens are validated with public keys fetched from a [JWKS](https://tools.ietf.org/html/rfc7517) URL provided in configuration. + +Validator-only mode is useful if you want to plug directly into an existing JWT-based workflow already being used in your system or organization. + +## 3. No authorization (default) +The interface is publicly available. + +# Configuration +- The API and Admin interfaces are each independently configured to run in one of the above-mentioned modes of operation. +- Authorization configuration is located under the `auth` key +- Each mode of operation has its own set of configuration properties, described below. + +## Issuer & Validator +The configuration properties pertaining to Issuer & Validator mode are listed below: + +|Property Name|Environment Variable|Description| +|---|---|---| +|ttl|TTL|Time-to-live of access tokens issued| +|hmacSecrets|HMACSECRETS|Array of secrets used to sign & validate access tokens, using the HMAC SHA256 algorithm. Values must be base64-format strings. The first value in the array is used to sign issued access tokens. Access tokens signed with any value in the array are considered valid.| +|clients|N/A|Array of objects, used for token issuance, consisting of `id`, `secretHash`, and `sdkKeys`. Clients provide ID and secret in their requests to `/oauth/token`. Agent validates the request credentials by checking for an exact match of ID, checking that the BCrypt hash of the request secret matches the `secretHash` from configuration, and that the SDK key provided in the `X-Optimizely-Sdk-Key` request header exists in the `sdkKeys` from configuration. `secretHash` values must be base64-format strings.| + +To make setup easier, Agent provides a command-line tool that can generate base64-encoded 32-byte random values, and their associated base64-encoded BCrypt hashes: + +```shell +// From the Agent root directory +> make generate_secret +Client Secret: i3SrdrCy/wEGqggv9OI4FgIsdHHNpOacrmIMJ6SFIkE= +Client Secret's hash: JDJhJDEyJERGNzhjRXVTNTdOQUZ3cndxTkZ6Li5XQURlazU2R21YeFZjb1pWSkN5eGZ1SXM4VXRLb0ZD +``` +Use the hash value to configure Agent, and pass the secret value as `client_secret` when making access token requests to `/oauth/token`. For details of the access token issuance endpoint, see the OpenAPI spec file. + +## Validator-only +The configuration properties pertaining to Validator-only mode are listed below: + +|Property Name|Environment Variable|Description| +|---|---|---| +|jwksURL|JWKSURL|URL from which public keys should be fetched for token validation| +|jwksUpdateInterval|JWKSUPDATEINTERVAL|Interval on which public keys should be re-fetched (example: `30m` for 30 minutes)| + +## No authorization (default) +The API & Admin interfaces run with no authorization when no `auth` configuration is given. + +## Configuration examples +Optimizely Agent uses the [Viper](https://github.com/spf13/viper) library for configuration, which allows setting values via environment variables, flags, and YAML configuration files. +### Issuer & Validator +_*WARNING*_: For security, we advise that you configure `hmacSecrets` with either an environment variable or a flag, and NOT through a config file. + +In the below example, the Admin interface is configured in Issuer & Validator mode, with `hmacSecrets` provided via environment variable, and other values provided via YAML config file. +```shell +// Comma-separated value, to set multiple hmacSecrets. +// Access tokens are signed with the first value. +// Access tokens are valid when they are signed with either of these values. +export OPTIMIZELY_ADMIN_HMACSECRETS=QPtUGP/RqaXRltZf1QE1KxlF2Iuo09J0buZ3UNKeIr0,bkZAqSsZuM5NSnwEyO9Pzb6F8gGNu1BBuX/SpPaMeyM +``` + +```yaml +admin: + auth: + # Access tokens will expire after 30 minutes + ttl: 30m + clients: + # Either of these two id/secret pairs can be exchanged for access tokens + - id: agentConsumer1 + secretHash: XgZTeTvWaZ6fLiey6EBSOxJ2QFdd6dIiUcZGDIIJ+IY + sdkKeys: + # These credentials can be exchanged for tokens granting access to these two SDK keys + - abcd1234 + - efgh5678 + - id: agentConsumer2 + secretHash: ssz0EEViKIinkFXxzqncKxz+6VygEc2d2rKf+la5rXM + sdkKeys: + # These credentials can be exchanged for tokens granting access only to this one SDK key + - ijkl9012 +``` + +### Validator-only +```yaml +# In this example, the API interface is configured in Validator-only mode +api: + auth: + # Signing keys will be fetched from this url and used when validating access tokens + jwksURL: https://YOUR_DOMAIN/.well-known/jwks.json + # Siging keys will be periodically fetched on this interval + jwksUpdateInterval: 30m +``` + +# Secret Rotation (Issuer & Validator mode) +To support secret rotation, both `hmacSecrets` and `clients` support setting multiple values. In `hmacSecrets`, the first value will be +used to sign issued tokens, but tokens signed with any of the values will be considered valid. + +# Example (Python) +Example requests demonstrating the Issuer & Validator mode: +```python +#!/usr/bin/python + +import json +import requests +import sys + +# This example demonstrates interacting with Agent running in Issuer & Validator mode. +# We obtain an access token and use it to request the current Optimizely Config +# from the API interface. + +# Fist, we need a secret value to sign access tokens. +# You can use the generate_secret tool included with Agent to generate this: + +# > make generate_secret +# Client Secret: CvzvkWm3V1D9RBxPWEjC+ud9zvwcOvnnLkWaIkzDGyA= + +# You can ignore the second line that says "Client Secret's hash". + +# Then, set an environment variable to make this secret available to Agent: +# > export OPTIMIZELY_API_AUTH_HMACSECRETS=CvzvkWm3V1D9RBxPWEjC+ud9zvwcOvnnLkWaIkzDGyA= + +# Next, we need client credentials (ID & secret), and the BCrypt hash of our secret +# Again, you can use the generate_secret tool included with Agent to generate these: +# +# > make generate_secret +# Client Secret: 0bfLVX9U3Lpr6Qe4X3DSSIWNqEkEQ4bkX1WZ5Km6spM= +# Client Secret's hash: JDJhJDEyJEdkSHpicHpRODBqOC9FQzRneGIyNXU0ZFVPMFNKcUhkdTRUQXRzWUJOdjRzRmcuVGdFUTUu +# +# Take the hash, and add it to your agent configuration file (default: config.yaml) under the "api" section, +# along with your desired client ID and SDK key: +# +# auth: +# ttl: 30m +# clients: +# - id: clientid1 +# secretHash: JDJhJDEyJEdkSHpicHpRODBqOC9FQzRneGIyNXU0ZFVPMFNKcUhkdTRUQXRzWUJOdjRzRmcuVGdFUTUu +# sdkKeys: +# - + +# +# Start Agent with the API interface running on the default port (8080). +# Then, finally, run the example, passing your SDK key, client ID and secret: +# > python auth.py clientid1 0bfLVX9U3Lpr6Qe4X3DSSIWNqEkEQ4bkX1WZ5Km6spM= +# +# For more information, see docs/auth.md + +if len(sys.argv) < 4: + sys.exit('Requires three arguments: ') + +sdk_key = sys.argv[1] +client_id = sys.argv[2] +client_secret = sys.argv[3] + +s = requests.Session() +s.headers.update({'X-Optimizely-SDK-Key': sdk_key}) + +resp = s.get('http://localhost:8080/v1/config') +print('first config request, not including access token: response status = {}'.format(resp.status_code)) + +resp = s.post('http://localhost:8080/oauth/token', data={ + 'grant_type': 'client_credentials', + 'client_id': client_id, + 'client_secret': client_secret, +}) +resp_dict = resp.json() +print('access token response: ') +print(json.dumps(resp_dict, indent=4, sort_keys=True)) + +s.headers.update({'Authorization': 'Bearer {}'.format(resp_dict['access_token'])}) + +resp = s.get('http://localhost:8080/v1/config') +print('config response after passing access token: ') +print(json.dumps(resp.json(), indent=4, sort_keys=True)) +``` \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md new file mode 100644 index 00000000..cbd14cb3 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md @@ -0,0 +1,41 @@ +--- +title: "Webhooks" +excerpt: "" +slug: "webhooks-agent" +hidden: false +metadata: + title: "Agent microservice webhooks - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:26.981Z" +updatedAt: "2020-05-05T17:03:48.045Z" +--- +Optimizely Agent implements a webhook listener used to receive inbound [Webhook](doc:configure-webhooks) requests from optimizely.com. These webhooks enable PUSH style notifications triggering immediate project configuration updates. +The webhook listener is configured on its own port (default: 8085) since it can be configured to select traffic from the internet. + +To accept webhook requests Agent must be configured by mapping an Optimizely Project Id to a set of SDK keys along +with the associated secret used for validating the inbound request. An example webhook configuration can be seen below, while the full example configuration can be found in the the provided [config.yaml](https://github.com/optimizely/agent/blob/master/config.yaml#L58). + +```yaml +## +## webhook service receives update notifications to your Optimizely project. Receipt of the webhook will +## trigger an immediate download of the datafile from the CDN +## +webhook: + ## http listener port + port: "8089" +# ## a map of Optimizely Projects to one or more SDK keys +# projects: +# ## : Optimizely project id as an integer +# : +# ## sdkKeys: a list of SDKs linked to this project +# sdkKeys: +# - +# - +# ## secret: webhook secret used the validate the notification +# secret: +# ## skipSignatureCheck: override the signature check (not recommended for production) +# skipSignatureCheck: true +``` + +## Next + +[Create Webhooks](https://docs.developers.optimizely.com/full-stack/docs/webhooks-agent) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md new file mode 100644 index 00000000..fa5b3605 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md @@ -0,0 +1,9 @@ +--- +title: "Docker Configurations" +excerpt: "" +slug: "docker-configurations" +hidden: true +createdAt: "2020-03-13T18:37:48.448Z" +updatedAt: "2020-03-13T18:37:48.448Z" +--- +Stub page for further info on how to configure docker? \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md new file mode 100644 index 00000000..f986333b --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md @@ -0,0 +1,57 @@ +--- +title: Agent Notifications +excerpt: "" +slug: "agent-notifications" +hidden: false +metadata: + title: "Agent notifications - Optimizely Full Stack" +createdAt: "2020-05-21T20:35:58.387Z" +updatedAt: "2020-07-14T20:51:52.458Z" +--- + +Agent provides an endpoint that sends notifications to subscribers via [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). This is Agent's equivalent of Notification Listeners found in Optimizely SDKs. + +For details on the notification types, what causes them to be triggered, and the data they provide, see the [Notification Listeners documentation](https://docs.developers.optimizely.com/full-stack/docs/set-up-notification-listener-go). + +## Configuration + +By default, the notifications endpoint is disabled. To enable it, change config.yaml: + +``` +# config.yaml +api: + enableNotifications: true +``` + +Or, enable it by setting an environment variable: + +``` +# set an env. variable +export OPTIMIZELY_API_ENABLENOTIFICATIONS=1 +``` + +## Usage + +Send a `GET` request to `/v1/notifications/event-stream` to subscribe: + +``` +curl -N -H "Accept:text/event-stream" -H "X-Optimizely-Sdk-Key:"\ + http://localhost:8080/v1/notifications/event-stream +``` + +This connection will remain open, and any notifications triggered by other requests received by Agent are pushed as events to this stream. Try sending requests to `/v1/activate` or `/v1/track` to see notifications being triggered. + + +### Filtering + +To subscribe only to a particular category of notifications, add a `filter` query parameter. For example, to subscribe only to Decision notifications: + +``` +# filter on decision notifications +curl -N -H "Accept:text/event-stream" -H "X-Optimizely-Sdk-Key:"\ + http://localhost:8080/v1/notifications/event-stream?filter=decision +``` + +## Example + +For a runnable Python example, see [examples/notifications.py](https://github.com/optimizely/agent/tree/master/examples). diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md new file mode 100644 index 00000000..24e30804 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md @@ -0,0 +1,56 @@ +--- +title: "Advanced configuration" +excerpt: "" +slug: "advanced-config-agent" +hidden: false +metadata: + title: "advanced config - Agent microservice - Optimizely Full Stack" +createdAt: "2020-05-21T20:35:58.387Z" +updatedAt: "2020-07-14T20:51:52.458Z" +--- + +## Setting Configuration Values + +Configuration can be provided to Agent via the following methods: + +1. Reading from environment variables +2. Reading from a YAML configuration file + +When a configuration option is specified through both methods, environment variables take precedence over the config file. + +Internally, Optimizely Agent uses the [Viper](https://github.com/spf13/viper) library's support for configuration files and environment variables. + +## Config File Location + +The default location of the config file is `config.yaml` in the root directory. If you want to specify another location, use the `OPTIMIZELY_CONFIG_FILENAME` environment variable: + +``` +OPTIMIZELY_CONFIG_FILENAME=/path/to/other_config_file.yaml make run +``` + +## Nested Configuration Options + +When setting the value of "nested" configuration options using environment variables, underscores denote deeper access. The following examples are equivalent ways of setting the client polling interval. + +Set the polling interval in YAML: + +``` +# Setting a nested value in a .yaml file: +client: + pollingInterval: 120s +``` + +Set the polling interval with a shell script: + +``` +# Set environment variable for pollingInterval, nested inside client +export OPTIMIZELY_CLIENT_POLLINGINTERVAL=120s +``` + +## Unsupported Environment Variable Options + +Some options can only be set via config file, and not environment variable (for details on these options, see the Configuration Options table in the [main README](https://github.com/optimizely/agent/blob/master/README.md): + +- `admin.auth.clients` +- `api.auth.clients` +- Options under`webhook.projects` diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md new file mode 100644 index 00000000..db908946 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md @@ -0,0 +1,86 @@ +--- +title: "Agent plugins" +excerpt: "" +slug: "agent-plugins" +hidden: false +metadata: + title: "Agent plugins - Optimizely Full Stack" +createdAt: "2020-09-21T20:30:00.000Z" +updatedAt: "2020-09-21T20:30:00.000Z" +--- + +## Agent Plugins + +Optimizely Agent can be extended through the use of plugins. Plugins are distinct from the standard Agent packages that provide a namespaced environment for custom logic. Plugins must be compiled as part of the Agent distribution and are enabled through configuration. + +### Interceptor Plugins + +Interceptors can be added to Agent to customize the request and/or response by implementing the [Interceptor](https://github.com/optimizely/agent/tree/master/plugins/interceptors/registry.go) interface. +This interface defines a `Handler()` method that returns a standard net/http middleware handler based on [http.Handler](https://golang.org/pkg/net/http/#Handler). +The interceptor struct can also include a set of fields that can be configured via `config.yaml`. + +* [httplog](https://github.com/optimizely/agent/tree/master/plugins/interceptors/httplog) - Adds HTTP request logging based on [go-chi/httplog](https://github.com/go-chi/httplog). + +### Example Interceptor definition +```go +package example + +import ( + "context" + "net/http" + + "github.com/optimizely/agent/plugins/interceptors" +) + +// Example implements the Interceptor plugin interface +type Example struct { + // set of configuration fields + RequestHeader string + ResponseHeader string + ContextValue string +} + +func (i *Example) Handler() func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.Header.Add("X-Example-Request", i.RequestHeader) + + // Example adding context to the request path + ctx := context.WithValue(r.Context(), "example-context", i.ContextValue) + + // Continuing with the normal serving + next.ServeHTTP(w, r.WithContext(ctx)) + + // Modify the response in some way + w.Header().Add("X-Example-Response", i.ResponseHeader) + }) + } +} + +// Register our interceptor as "example". +func init() { + interceptors.Add("example", func() interceptors.Interceptor { + return &Example{} + }) +} +``` + +To make the interceptor available to Agent, add the plugin as an anonymous import into [all.go](./interceptors/all/all.go). +```go +package all + +// Add imports here to trigger the plugin `init()` function +import ( + _ "github.com/optimizely/agent/plugins/interceptors/example" +) +``` + +Enable the example interceptor by adding to `server.interceptors` within your `config.yaml`. Note that the yaml fields should match the struct definition of your plugin. +```yaml +server: + interceptors: + example: + requestHeader: "example-request" + responseHeader: "example-response" + contextValue: "example-context" +``` diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md new file mode 100644 index 00000000..d4f936f0 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md @@ -0,0 +1,56 @@ +--- +title: "Configure Optimizely Agent" +excerpt: "" +slug: "configure-optimizely-agent" +hidden: false +metadata: + title: "Configure Agent microservice - Optimizely Full Stack" +createdAt: "2020-02-21T17:44:27.173Z" +updatedAt: "2020-04-08T21:42:08.698Z" +--- +By default Optimizely Agent uses the configuration file in the current active directory, e.g., `./config.yaml`. You can override the [default configuration](https://github.com/optimizely/agent/blob/master/config.yaml) by providing a yaml configuration file at runtime. + +You can specify alternative configuration locations at runtime via an environment variable or command line flag: + +```bash +OPTIMIZELY_CONFIG_FILENAME=config.yaml make run +``` + + +Below is a comprehensive list of available configuration properties. + +|Property Name|Env Variable|Description| +|---|---|---| +|admin.auth.clients|N/A|Credentials for requesting access tokens. See: [Authorization Guide](doc:authorization)| +|admin.auth.jwksURL|OPTIMIZELY_ADMIN_AUTH_JWKSURL|JWKS URL for validating access tokens. See: [Authorization Guide](doc:authorization)| +|admin.auth.jwksUpdateInterval|OPTIMIZELY_ADMIN_AUTH_JWKSUPDATEINTERVAL|JWKS Update Interval for caching the keys in the background. See: [Authorization Guide](doc:authorization)| +|admin.auth.hmacSecrets|OPTIMIZELY_ADMIN_AUTH_HMACSECRETS|Signing secret for issued access tokens. See: [Authorization Guide](doc:authorization)| +|admin.auth.ttl|OPTIMIZELY_ADMIN_AUTH_TTL|Time-to-live of issued access tokens. See: [Authorization Guide](doc:authorization)| +|admin.port|OPTIMIZELY_ADMIN_PORT|Admin listener port. Default: 8088| +|api.auth.clients|N/A|Credentials for requesting access tokens. See: [Authorization Guide](doc:authorization)| +|api.auth.hmacSecrets|OPTIMIZELY_API_AUTH_HMACSECRETS|Signing secret for issued access tokens. See: [Authorization Guide](doc:authorization)| +|api.auth.jwksURL|OPTIMIZELY_API_AUTH_JWKSURL|JWKS URL for validating access tokens. See: [Authorization Guide](doc:authorization)| +|api.auth.jwksUpdateInterval|OPTIMIZELY_API_AUTH_JWKSUPDATEINTERVAL|JWKS Update Interval for caching the keys in the background. See: [Authorization Guide](doc:authorization)| +|api.auth.ttl|OPTIMIZELY_API_AUTH_TTL|Time-to-live of issued access tokens. See: [Authorization Guide](doc:authorization)| +|api.port|OPTIMIZELY_API_PORT|Api listener port. Default: 8080| +|api.maxConns|OPTIMIZLEY_API_MAXCONNS|Maximum number of concurrent requests| +|author|OPTIMIZELY_AUTHOR|Agent author. Default: Optimizely Inc.| +|certfile|OPTIMIZELY_CERTFILE|Path to a certificate file, used to run Agent with HTTPS| +|client.batchSize|OPTIMIZELY_CLIENT_BATCHSIZE|The number of events in a batch. Default: 10| +|config.filename|OPTIMIZELY_CONFIG_FILENAME|Location of the configuration YAML file. Default: ./config.yaml| +|client.flushInterval|OPTIMIZELY_CLIENT_FLUSHINTERVAL|The maximum time between events being dispatched. Default: 30s| +|client.pollingInterval|OPTIMIZELY_CLIENT_POLLINGINTERVAL|The time between successive polls for updated project configuration. Default: 1m| +|client.queueSize|OPTIMIZELY_CLIENT_QUEUESIZE|The max number of events pending dispatch. Default: 1000| +|disabledCiphers|OPTIMIZELY_DISABLEDCIPHERS|List of TLS ciphers to disable when accepting HTTPS connections| +|keyfile|OPTIMIZELY_KEYFILE|Path to a key file, used to run Agent with HTTPS| +|log.level|OPTIMIZELY_LOG_LEVEL|The log [level](https://github.com/rs/zerolog#leveled-logging) for the agent. Default: info| +|log.pretty|OPTIMIZELY_LOG_PRETTY|Flag used to set colorized console output as opposed to structured json logs. Default: false| +|name|OPTIMIZELY_NAME|Agent name. Default: optimizely| +|version|OPTIMIZELY_VERSION|Agent version. Default: `git describe --tags`| +|sdkKeys|OPTIMIZELY_SDKKEYS|List of SDK keys used to initialize on startup| +|server.readTimeout|OPTIMIZELY_SERVER_READTIMEOUT|The maximum duration for reading the entire body. Default: “5s”| +|server.writeTimeout|OPTIMIZELY_SERVER_WRITETIMEOUT|The maximum duration before timing out writes of the response. Default: “10s”| +|webhook.port|OPTIMIZELY_WEBHOOK_PORT|Webhook listener port: Default: 8085| +|webhook.projects.<*projectId*>.sdkKeys|N/A|Comma delimited list of SDK keys applicable to the respective projectId| +|webhook.projects.<*projectId*>.secret|N/A|Webhook secret used to validate webhook requests originating from the respective projectId| +|webhook.projects.<*projectId*>.skipSignatureCheck|N/A|Boolean to indicate whether the signature should be validated. TODO remove in favor of empty secret.| diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md new file mode 100644 index 00000000..3649a8a6 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md @@ -0,0 +1,11 @@ +--- +title: "API Reference" +excerpt: "" +slug: "api-reference" +hidden: false +createdAt: "2020-02-21T17:44:52.492Z" +updatedAt: "2020-02-21T17:44:52.492Z" +type: "link" +link_url: "https://optimizely.github.io/docs/api/agent/" +link_external: true +--- diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md new file mode 100644 index 00000000..ae341515 --- /dev/null +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md @@ -0,0 +1,11 @@ +--- +title: "Github Repository" +excerpt: "" +slug: "github-repository" +hidden: false +createdAt: "2020-02-21T17:44:28.559Z" +updatedAt: "2020-02-21T17:44:28.559Z" +type: "link" +link_url: "https://github.com/optimizely/agent" +link_external: true +--- From 98049fb20b135ac5dc789e157fe769942c5cf704 Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Mon, 18 Jan 2021 16:05:27 -0700 Subject: [PATCH 02/11] editing docs in typora --- .../030 - use-optimizely-agent/index.md | 40 +++++++++---------- .../050 - api-reference.md | 2 +- .../012 - quickstart-for-agent.md | 12 +++--- .../050 - api-reference.md | 2 +- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 38c06368..e95df04c 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,45 +9,45 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable feature flag-based A/B tests and feature flag delivery. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). -### Manage features +### Decide flags - Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: -- [isFeatureEnabled](doc:is-feature-enabled-go) -- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) -- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) -- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) -- [getFeatureVariableString](doc:get-feature-variable-go#section-string) -- [getEnabledFeatures](doc:get-enabled-features-go) +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide): +`POST /v1/decide?keys={flagKey}` -... into one, convenient endpoint: +returns an array of OptimizelyDecision objects that contain information such as: -`POST /v1/activate?featureKey={featureKey}` - -This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: - -- the decision for this feature for this user -- any corresponding feature variable values. +- the decision for this flag for this user +- any corresponding feature flag variable values. For example: ```json { - "featureKey": "feature-key-1", + "userContext": { + "UserId": "test-user", + "Attributes": { + "logged-in": true, + "location": "usa" + } + }, + "flagKey": "my-feature-flag", + "ruleKey": "my-a-b-test", "enabled": true, "variables": { "my-var-1": "cust-val-1", "my-var-2": "cust-va1-2" - } + }, + "reasons": [""] } ``` -The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. +The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is assigned to a feature test, this API will dispatch an impression. +Note: If the user is assigned to an A/B test, this API will dispatch a decision event. ### Authentication diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md index 3649a8a6..152953a7 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/050 - api-reference.md @@ -6,6 +6,6 @@ hidden: false createdAt: "2020-02-21T17:44:52.492Z" updatedAt: "2020-02-21T17:44:52.492Z" type: "link" -link_url: "https://optimizely.github.io/docs/api/agent/" +link_url: "https://library.optimizely.com/docs/api/agent/v1/index.html" link_external: true --- diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index 92a8cc16..97b36c1b 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -71,18 +71,18 @@ for key in env['featuresMap']: print(key) ``` -### Activate Feature +### Decide a feature flag -The `/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. +The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. -From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. +This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. ```python -params = { "featureKey": "my-feature" } +params = { "keys": "my-feature-flag" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. +The decide API is a POST to signal to the caller that there are side-effects. Namely, this endpoint results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. A "decision" will NOT be sent if the feature flag is simply part of a delivery. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md index 3649a8a6..152953a7 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md @@ -6,6 +6,6 @@ hidden: false createdAt: "2020-02-21T17:44:52.492Z" updatedAt: "2020-02-21T17:44:52.492Z" type: "link" -link_url: "https://optimizely.github.io/docs/api/agent/" +link_url: "https://library.optimizely.com/docs/api/agent/v1/index.html" link_external: true --- From b8808d0fd940c11d99628ed3d2c11ad97e47faef Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 11:02:53 -0700 Subject: [PATCH 03/11] local typora edits --- .../010 - evaluate-rest-apis.md | 4 +- .../030 - use-optimizely-agent/index.md | 75 +++++++++++-------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md index e06bd6be..a5dd0c42 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -33,8 +33,8 @@ for key in env['featuresMap']: print(key) ``` -## Activate Feature -The `/v1/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. +## Run flag rules +The `POST /v1/decide?keys={flagKey}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index e95df04c..d2cb95ba 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,18 +9,37 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable feature flag-based A/B tests and feature flag delivery. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). -### Decide flags +### Running flag rules -The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide): +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) lets you run flag rules, such as A/B tests or targeted feature flag deliveries. To run a flag rule, use: `POST /v1/decide?keys={flagKey}` -returns an array of OptimizelyDecision objects that contain information such as: +In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: + +```curl +curl --request POST 'http://localhost:8080/v1/decide' \ +--header 'Content-Type: application/json' \ +--header 'X-Optimizely-SDK-Key: ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ +"userId": "test-user" +"decideOptions": [ + "INCLUDE_REASONS" +] +}' +``` + +TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE + + -- the decision for this flag for this user +This returns an array of OptimizelyDecision objects that contains all the information you need to run your flag rule, such as: + +- the decision to bucket this user into an enabled or disabled feature flag variation. - any corresponding feature flag variable values. For example: @@ -36,53 +55,43 @@ For example: }, "flagKey": "my-feature-flag", "ruleKey": "my-a-b-test", - "enabled": true, + "enabled": false, + "variationKey": "control_variation" "variables": { - "my-var-1": "cust-val-1", - "my-var-2": "cust-va1-2" + "my-var-1": "cust-val-default-1", + "my-var-2": "cust-va1-default-2" }, - "reasons": [""] + "reasons": [] } ``` The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is assigned to an A/B test, this API will dispatch a decision event. +Note: If the user is bucketed into an A/B test, this endpoint dispatches a decision event. ### Authentication To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. +### Get All Decisions +To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: +`POST /v1/decide` -### Running A/B tests - - -To activate an A/B test, use: +To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: -`POST /v1/activate?experimentKey={experimentKey}` +```curl +--header 'Content-Type: application/json' \ -This dispatches an impression and return the user’s assigned variation: +--data-raw '{ +"userId": "test-user" -`POST /v1/activate?experimentKey={experimentKey}` +"decideOptions": [ + "ENABLED_FLAGS_ONLY" +] -This dispatches an impression and return the user’s assigned variation: -```json -{ - "experimentKey": "experiment-key-1", - "variationKey": "variation-key-1" -} +}' ``` -### Get All Decisions -To get all Feature decisions for a visitor in a single request use: -`POST /v1/activate?type=feature` - -To receive only the enabled features for a visitor use: - -`POST /v1/activate?type=feature&enabled=true` - -To get all Experiment decisions for a visitor in a single request use: -`POST /v1/activate?type=experiment` From a168b41e49e4edf71f36603d07d8dfc4fe97813f Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 12:14:12 -0700 Subject: [PATCH 04/11] revert mistaken changes to v3.1 docs --- .../012 - quickstart-for-agent.md | 2 +- .../030 - use-optimizely-agent/index.md | 99 +++++++++---------- .../030 - use-optimizely-agent/index.md | 99 ++++++++++--------- 3 files changed, 101 insertions(+), 99 deletions(-) diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md index 92a8cc16..d0e3a8da 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -85,4 +85,4 @@ resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=pay print(resp.json()) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. \ No newline at end of file diff --git a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index d2cb95ba..604508f8 100644 --- a/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v3.1/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,89 +9,80 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. -### Running flag rules +### Manage features + Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: -The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) lets you run flag rules, such as A/B tests or targeted feature flag deliveries. To run a flag rule, use: +- [isFeatureEnabled](doc:is-feature-enabled-go) +- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) +- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) +- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) +- [getFeatureVariableString](doc:get-feature-variable-go#section-string) +- [getEnabledFeatures](doc:get-enabled-features-go) -`POST /v1/decide?keys={flagKey}` - -In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: - -```curl -curl --request POST 'http://localhost:8080/v1/decide' \ ---header 'Content-Type: application/json' \ ---header 'X-Optimizely-SDK-Key: ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ -"userId": "test-user" -"decideOptions": [ - "INCLUDE_REASONS" -] -}' -``` - -TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE +... into one, convenient endpoint: +`POST /v1/activate?featureKey={featureKey}` -This returns an array of OptimizelyDecision objects that contains all the information you need to run your flag rule, such as: +This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: -- the decision to bucket this user into an enabled or disabled feature flag variation. -- any corresponding feature flag variable values. +- the decision for this feature for this user +- any corresponding feature variable values. For example: ```json { - "userContext": { - "UserId": "test-user", - "Attributes": { - "logged-in": true, - "location": "usa" - } - }, - "flagKey": "my-feature-flag", - "ruleKey": "my-a-b-test", - "enabled": false, - "variationKey": "control_variation" + "featureKey": "feature-key-1", + "enabled": true, "variables": { - "my-var-1": "cust-val-default-1", - "my-var-2": "cust-va1-default-2" - }, - "reasons": [] + "my-var-1": "cust-val-1", + "my-var-2": "cust-va1-2" + } } ``` -The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. +The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is bucketed into an A/B test, this endpoint dispatches a decision event. +Note: If the user is assigned to a feature test, this API will dispatch an impression. ### Authentication To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. -### Get All Decisions -To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: -`POST /v1/decide` -To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: +### Running A/B tests + + +To activate an A/B test, use: -```curl ---header 'Content-Type: application/json' \ +`POST /v1/activate?experimentKey={experimentKey}` ---data-raw '{ -"userId": "test-user" +This dispatches an impression and return the user’s assigned variation: -"decideOptions": [ - "ENABLED_FLAGS_ONLY" -] +`POST /v1/activate?experimentKey={experimentKey}` -}' +This dispatches an impression and return the user’s assigned variation: +```json +{ + "experimentKey": "experiment-key-1", + "variationKey": "variation-key-1" +} ``` +### Get All Decisions +To get all Feature decisions for a visitor in a single request use: +`POST /v1/activate?type=feature` + +To receive only the enabled features for a visitor use: + +`POST /v1/activate?type=feature&enabled=true` + +To get all Experiment decisions for a visitor in a single request use: +`POST /v1/activate?type=experiment` @@ -105,4 +96,4 @@ There is no response body for successful conversion event requests. ### API reference - For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). + For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 38c06368..28c3d36e 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,80 +9,91 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). -### Manage features +### Running flag rules - Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: -- [isFeatureEnabled](doc:is-feature-enabled-go) -- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) -- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) -- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) -- [getFeatureVariableString](doc:get-feature-variable-go#section-string) -- [getEnabledFeatures](doc:get-enabled-features-go) +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) lets you run flag rules, such as A/B tests or targeted feature flag deliveries. To run a flag rule, use: +`POST /v1/decide?keys={flagKey}` + +In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: + +```curl +curl --request POST 'http://localhost:8080/v1/decide' \ +--header 'Content-Type: application/json' \ +--header 'X-Optimizely-SDK-Key: ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ +"userId": "test-user" +"decideOptions": [ + "INCLUDE_REASONS" +] +}' +``` + +TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE -... into one, convenient endpoint: -`POST /v1/activate?featureKey={featureKey}` -This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: +This returns an array of OptimizelyDecision objects that contains all the information you need to run your flag rule, such as: -- the decision for this feature for this user -- any corresponding feature variable values. +- the decision to bucket this user into an enabled or disabled feature flag variation. +- any corresponding feature flag variable values. For example: ```json { - "featureKey": "feature-key-1", - "enabled": true, + "userContext": { + "UserId": "test-user", + "Attributes": { + "logged-in": true, + "location": "usa" + } + }, + "flagKey": "my-feature-flag", + "ruleKey": "my-a-b-test", + "enabled": false, + "variationKey": "control_variation" "variables": { - "my-var-1": "cust-val-1", - "my-var-2": "cust-va1-2" - } + "my-var-1": "cust-val-default-1", + "my-var-2": "cust-va1-default-2" + }, + "reasons": [] } ``` -The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. +The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is assigned to a feature test, this API will dispatch an impression. +Note: If the user is bucketed into an A/B test, this endpoint dispatches a decision event. ### Authentication To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. +### Get All Decisions +- To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: + `POST /v1/decide` +- To get decisions for multiple keys, specify multiple keys parameters: + `keys={flag_key_1}&keys={flag_key_2}` -### Running A/B tests - - -To activate an A/B test, use: +- To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: -`POST /v1/activate?experimentKey={experimentKey}` +```curl +--header 'Content-Type: application/json' \ -This dispatches an impression and return the user’s assigned variation: +--data-raw '{ +"userId": "test-user" -`POST /v1/activate?experimentKey={experimentKey}` +"decideOptions": [ + "ENABLED_FLAGS_ONLY" +] -This dispatches an impression and return the user’s assigned variation: -```json -{ - "experimentKey": "experiment-key-1", - "variationKey": "variation-key-1" -} +}' ``` -### Get All Decisions -To get all Feature decisions for a visitor in a single request use: -`POST /v1/activate?type=feature` - -To receive only the enabled features for a visitor use: - -`POST /v1/activate?type=feature&enabled=true` - -To get all Experiment decisions for a visitor in a single request use: -`POST /v1/activate?type=experiment` From 39e8cf69372be267fdb6e8f97c439ff5c0220dca Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 13:07:55 -0700 Subject: [PATCH 05/11] local typora edits --- .../012 - quickstart-for-agent.md | 6 ++--- .../010 - evaluate-rest-apis.md | 27 ++++++++++--------- .../030 - use-optimizely-agent/index.md | 10 ++++--- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index 97b36c1b..0d2991b6 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -71,9 +71,9 @@ for key in env['featuresMap']: print(key) ``` -### Decide a feature flag +### Run a feature flag rule -The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. +The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule and flag variation the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. @@ -85,4 +85,4 @@ resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=paylo print(resp.json()) ``` -The decide API is a POST to signal to the caller that there are side-effects. Namely, this endpoint results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. A "decision" will NOT be sent if the feature flag is simply part of a delivery. +The decide API is a POST to signal to the caller that there are side-effects. Namely, this endpoint results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. By default a "decision" is not sent if the feature flag is simply part of a delivery. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md index e06bd6be..d975d560 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -33,27 +33,28 @@ for key in env['featuresMap']: print(key) ``` -## Activate Feature -The `/v1/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. +## Run a feature flag rule -From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled variations or one disabled variation) as part of a flag rule. Flag rules let you: +- experiment using A/B tests +- roll out feature flags progressively to a selected audience using targeted feature flag deliveries. +To run a flag rule, use ```python -# single feature activate -params = { "featureKey": "my-feature" } +# decide 1 flag. +params = { "keys": "my-feature-flag" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) -# multiple (bulk) feature activate -params = { - "featureKey": [key for key in env['featuresMap']], - "experimentKey": [key for key in env['experimentsMap']] -} -resp2 = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +# multiple (bulk) feature flag decisions for specified flags. +# To decide ALL flags, simply omit keys params +payload = { "userId": "test-user" } +params = {"keys":"flag_1", "keys":"flag_2"} +resp2 = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(json.dumps(resp.json(), indent=4, sort_keys=True)) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. +The decide API is a POST to signal to the caller that there are side-effects. Namely, the decision results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. A decision event will NOT be sent by default if the flag is simply part of a delivery. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 28c3d36e..5be6bc6c 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -11,10 +11,10 @@ updatedAt: "2020-04-08T21:26:30.308Z" Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). -### Running flag rules +### Running feature flag rules -The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) lets you run flag rules, such as A/B tests or targeted feature flag deliveries. To run a flag rule, use: +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled or one disabled variation) as part of a flag rule. Flag rules include A/B tests and targeted feature flag deliveries. To run a flag rule, use: `POST /v1/decide?keys={flagKey}` @@ -77,8 +77,10 @@ To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/ful ### Get All Decisions - To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: `POST /v1/decide` -- To get decisions for multiple keys, specify multiple keys parameters: - `keys={flag_key_1}&keys={flag_key_2}` +- To get decisions for multiple keys, specify multiple keys parameters, for example: + `keys=flag_key_1&keys=flag_key_2` + + TODO: is above example right? - To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: From b53d49bc145f2a162970741e1dfaf2197e2d86af Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 13:16:04 -0700 Subject: [PATCH 06/11] split off raptor/decide edit into new PR --- .../012 - quickstart-for-agent.md | 12 +- .../010 - evaluate-rest-apis.md | 27 +++-- .../030 - use-optimizely-agent/index.md | 103 ++++++++---------- 3 files changed, 64 insertions(+), 78 deletions(-) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index 0d2991b6..d0e3a8da 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -71,18 +71,18 @@ for key in env['featuresMap']: print(key) ``` -### Run a feature flag rule +### Activate Feature -The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule and flag variation the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. +The `/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. -This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. +From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. ```python -params = { "keys": "my-feature-flag" } +params = { "featureKey": "my-feature" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) print(resp.json()) ``` -The decide API is a POST to signal to the caller that there are side-effects. Namely, this endpoint results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. By default a "decision" is not sent if the feature flag is simply part of a delivery. +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md index d975d560..a5dd0c42 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -33,28 +33,27 @@ for key in env['featuresMap']: print(key) ``` -## Run a feature flag rule +## Run flag rules +The `POST /v1/decide?keys={flagKey}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. -The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled variations or one disabled variation) as part of a flag rule. Flag rules let you: -- experiment using A/B tests -- roll out feature flags progressively to a selected audience using targeted feature flag deliveries. +From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. -To run a flag rule, use ```python -# decide 1 flag. -params = { "keys": "my-feature-flag" } +# single feature activate +params = { "featureKey": "my-feature" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) print(resp.json()) -# multiple (bulk) feature flag decisions for specified flags. -# To decide ALL flags, simply omit keys params -payload = { "userId": "test-user" } -params = {"keys":"flag_1", "keys":"flag_2"} -resp2 = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) +# multiple (bulk) feature activate +params = { + "featureKey": [key for key in env['featuresMap']], + "experimentKey": [key for key in env['experimentsMap']] +} +resp2 = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) print(json.dumps(resp.json(), indent=4, sort_keys=True)) ``` -The decide API is a POST to signal to the caller that there are side-effects. Namely, the decision results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. A decision event will NOT be sent by default if the flag is simply part of a delivery. +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 5be6bc6c..604508f8 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,93 +9,80 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. -### Running feature flag rules +### Manage features + Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: -The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled or one disabled variation) as part of a flag rule. Flag rules include A/B tests and targeted feature flag deliveries. To run a flag rule, use: +- [isFeatureEnabled](doc:is-feature-enabled-go) +- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) +- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) +- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) +- [getFeatureVariableString](doc:get-feature-variable-go#section-string) +- [getEnabledFeatures](doc:get-enabled-features-go) -`POST /v1/decide?keys={flagKey}` - -In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: - -```curl -curl --request POST 'http://localhost:8080/v1/decide' \ ---header 'Content-Type: application/json' \ ---header 'X-Optimizely-SDK-Key: ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ -"userId": "test-user" -"decideOptions": [ - "INCLUDE_REASONS" -] -}' -``` - -TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE +... into one, convenient endpoint: +`POST /v1/activate?featureKey={featureKey}` -This returns an array of OptimizelyDecision objects that contains all the information you need to run your flag rule, such as: +This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: -- the decision to bucket this user into an enabled or disabled feature flag variation. -- any corresponding feature flag variable values. +- the decision for this feature for this user +- any corresponding feature variable values. For example: ```json { - "userContext": { - "UserId": "test-user", - "Attributes": { - "logged-in": true, - "location": "usa" - } - }, - "flagKey": "my-feature-flag", - "ruleKey": "my-a-b-test", - "enabled": false, - "variationKey": "control_variation" + "featureKey": "feature-key-1", + "enabled": true, "variables": { - "my-var-1": "cust-val-default-1", - "my-var-2": "cust-va1-default-2" - }, - "reasons": [] + "my-var-1": "cust-val-1", + "my-var-2": "cust-va1-2" + } } ``` -The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. +The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is bucketed into an A/B test, this endpoint dispatches a decision event. +Note: If the user is assigned to a feature test, this API will dispatch an impression. ### Authentication To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. -### Get All Decisions -- To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: - `POST /v1/decide` -- To get decisions for multiple keys, specify multiple keys parameters, for example: - `keys=flag_key_1&keys=flag_key_2` - - TODO: is above example right? -- To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: +### Running A/B tests + + +To activate an A/B test, use: -```curl ---header 'Content-Type: application/json' \ +`POST /v1/activate?experimentKey={experimentKey}` ---data-raw '{ -"userId": "test-user" +This dispatches an impression and return the user’s assigned variation: -"decideOptions": [ - "ENABLED_FLAGS_ONLY" -] +`POST /v1/activate?experimentKey={experimentKey}` -}' +This dispatches an impression and return the user’s assigned variation: +```json +{ + "experimentKey": "experiment-key-1", + "variationKey": "variation-key-1" +} ``` +### Get All Decisions +To get all Feature decisions for a visitor in a single request use: +`POST /v1/activate?type=feature` + +To receive only the enabled features for a visitor use: + +`POST /v1/activate?type=feature&enabled=true` + +To get all Experiment decisions for a visitor in a single request use: +`POST /v1/activate?type=experiment` @@ -109,4 +96,4 @@ There is no response body for successful conversion event requests. ### API reference - For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). + For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). \ No newline at end of file From c937c987404aec876c0acd4bb9c69fa66a765e2e Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 13:24:48 -0700 Subject: [PATCH 07/11] clean diff v3.1 vs 4.0 docs raptor & decide terminology/endpoint update --- .../012 - quickstart-for-agent.md | 12 +- .../010 - evaluate-rest-apis.md | 27 ++--- .../030 - use-optimizely-agent/index.md | 103 ++++++++++-------- 3 files changed, 78 insertions(+), 64 deletions(-) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index d0e3a8da..0d2991b6 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -71,18 +71,18 @@ for key in env['featuresMap']: print(key) ``` -### Activate Feature +### Run a feature flag rule -The `/activate?featureKey={key}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. +The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule and flag variation the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. -From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. +This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. ```python -params = { "featureKey": "my-feature" } +params = { "keys": "my-feature-flag" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. \ No newline at end of file +The decide API is a POST to signal to the caller that there are side-effects. Namely, this endpoint results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. By default a "decision" is not sent if the feature flag is simply part of a delivery. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md index a5dd0c42..d975d560 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -33,27 +33,28 @@ for key in env['featuresMap']: print(key) ``` -## Run flag rules -The `POST /v1/decide?keys={flagKey}` endpoint activates the feature for a given user. In Optimizely, activation is in the context of a given user to make the relative bucketing decision. In this case we'll provide a `userId` via the request body. The `userId` will be used to determine how the feature will be evaluated. Features can either be part of a Feature Test in which variations of feature variables are being measured against one another or a feature rollout, which progressively make the feature available to the selected audience. +## Run a feature flag rule -From an API standpoint the presence of a Feature Test or Rollout is abstracted away from the response and only the resulting variation or enabled feature is returned. +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled variations or one disabled variation) as part of a flag rule. Flag rules let you: +- experiment using A/B tests +- roll out feature flags progressively to a selected audience using targeted feature flag deliveries. +To run a flag rule, use ```python -# single feature activate -params = { "featureKey": "my-feature" } +# decide 1 flag. +params = { "keys": "my-feature-flag" } payload = { "userId": "test-user" } -resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) -# multiple (bulk) feature activate -params = { - "featureKey": [key for key in env['featuresMap']], - "experimentKey": [key for key in env['experimentsMap']] -} -resp2 = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=payload) +# multiple (bulk) feature flag decisions for specified flags. +# To decide ALL flags, simply omit keys params +payload = { "userId": "test-user" } +params = {"keys":"flag_1", "keys":"flag_2"} +resp2 = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(json.dumps(resp.json(), indent=4, sort_keys=True)) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. +The decide API is a POST to signal to the caller that there are side-effects. Namely, the decision results in a "decision" event sent to Optimizely analytics for the purpose of analyzing A/B test results. A decision event will NOT be sent by default if the flag is simply part of a delivery. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 604508f8..5be6bc6c 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -9,80 +9,93 @@ createdAt: "2020-02-21T17:44:28.054Z" updatedAt: "2020-04-08T21:26:30.308Z" --- -Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable experimentation and feature management. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). In some cases, however, we’ve updated our APIs to simplify key use cases. +Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). -### Manage features +### Running feature flag rules - Optimizely Agent simplifies the core feature management of our [SDK APIs](doc:sdk-reference-guides). It consolidates the following endpoints: -- [isFeatureEnabled](doc:is-feature-enabled-go) -- [getFeatureVariableBoolean](doc:get-feature-variable-go#section-boolean) -- [getFeatureVariableDouble](doc:get-feature-variable-go#section-double) -- [getFeatureVariableInteger](doc:get-feature-variable-go#section-integer) -- [getFeatureVariableString](doc:get-feature-variable-go#section-string) -- [getEnabledFeatures](doc:get-enabled-features-go) +The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/decide) buckets a user into a feature flag variation (choosing between multiple enabled or one disabled variation) as part of a flag rule. Flag rules include A/B tests and targeted feature flag deliveries. To run a flag rule, use: +`POST /v1/decide?keys={flagKey}` + +In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: + +```curl +curl --request POST 'http://localhost:8080/v1/decide' \ +--header 'Content-Type: application/json' \ +--header 'X-Optimizely-SDK-Key: ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ +"userId": "test-user" +"decideOptions": [ + "INCLUDE_REASONS" +] +}' +``` + +TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE -... into one, convenient endpoint: -`POST /v1/activate?featureKey={featureKey}` -This [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.html#operation/activate) returns: +This returns an array of OptimizelyDecision objects that contains all the information you need to run your flag rule, such as: -- the decision for this feature for this user -- any corresponding feature variable values. +- the decision to bucket this user into an enabled or disabled feature flag variation. +- any corresponding feature flag variable values. For example: ```json { - "featureKey": "feature-key-1", - "enabled": true, + "userContext": { + "UserId": "test-user", + "Attributes": { + "logged-in": true, + "location": "usa" + } + }, + "flagKey": "my-feature-flag", + "ruleKey": "my-a-b-test", + "enabled": false, + "variationKey": "control_variation" "variables": { - "my-var-1": "cust-val-1", - "my-var-2": "cust-va1-2" - } + "my-var-1": "cust-val-default-1", + "my-var-2": "cust-va1-default-2" + }, + "reasons": [] } ``` -The response is determined by the [feature tests](doc:run-feature-tests) and [feature rollouts](doc:use-feature-flags) defined for the supplied feature key, following the same rules as any Full Stack SDK. +The response is determined by the [A/B tests](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-a-b-tests) and [deliveries](https://docs.developers.optimizely.com/full-stack/v4.0/docs/run-flag-deliveries) defined for the supplied feature key, following the same rules as any Full Stack SDK. -Note: If the user is assigned to a feature test, this API will dispatch an impression. +Note: If the user is bucketed into an A/B test, this endpoint dispatches a decision event. ### Authentication To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/full-stack/docs/evaluate-rest-apis#section-start-an-http-session) as a header named ```X-Optimizely-SDK-Key``` in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember you have a different SDK key for each environment. +### Get All Decisions +- To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter: + `POST /v1/decide` +- To get decisions for multiple keys, specify multiple keys parameters, for example: + `keys=flag_key_1&keys=flag_key_2` + + TODO: is above example right? -### Running A/B tests - - -To activate an A/B test, use: +- To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: -`POST /v1/activate?experimentKey={experimentKey}` +```curl +--header 'Content-Type: application/json' \ -This dispatches an impression and return the user’s assigned variation: +--data-raw '{ +"userId": "test-user" -`POST /v1/activate?experimentKey={experimentKey}` +"decideOptions": [ + "ENABLED_FLAGS_ONLY" +] -This dispatches an impression and return the user’s assigned variation: -```json -{ - "experimentKey": "experiment-key-1", - "variationKey": "variation-key-1" -} +}' ``` -### Get All Decisions -To get all Feature decisions for a visitor in a single request use: -`POST /v1/activate?type=feature` - -To receive only the enabled features for a visitor use: - -`POST /v1/activate?type=feature&enabled=true` - -To get all Experiment decisions for a visitor in a single request use: -`POST /v1/activate?type=experiment` @@ -96,4 +109,4 @@ There is no response body for successful conversion event requests. ### API reference - For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). \ No newline at end of file + For more details on Optimizely Agent’s APIs, see the [complete API Reference](https://library.optimizely.com/docs/api/agent/v1/index.html). From 5436c4d5f4f8b3646e6114cb9e3342aff5ddf1ca Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Tue, 19 Jan 2021 13:26:48 -0700 Subject: [PATCH 08/11] undo test ordering of stages --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 33365230..93ddc484 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,15 +15,14 @@ branches: - /^v\d+\.\d+(\.\d+)?(-\S*)?$/ stages: - - 'Readme-sync-preview' - - 'Readme-sync' - 'Tests' - 'Trigger FSC Tests' - 'Test Build using latest tag (no upload)' - 'Build, Upload and Publish (draft)' - 'Test github release assets' - 'Publish (real)' - + - 'Readme-sync-preview' + - 'Readme-sync' jobs: From eefee340bdb1b392971388d25b3550186e2d4dd0 Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:54:41 -0600 Subject: [PATCH 09/11] responding to review requests --- .../001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md | 2 +- .../010 - optimizely-agent.md | 2 +- .../012 - quickstart-for-agent.md | 11 +++++++--- .../020 - setup-optimizely-agent.md | 2 +- .../010 - evaluate-rest-apis.md | 11 ++++++++-- .../020 - admin-api.md | 2 +- .../030 - use-optimizely-agent/index.md | 22 ++++++++++--------- .../010 - authorization.md | 2 +- .../020 - webhooks-agent.md | 2 +- .../030 - docker-configurations.md | 2 +- .../031 - agent-notifications.md | 2 +- .../040 - advanced-configuration.md | 2 +- .../050 - agent-plugins.md | 2 +- .../040 - configure-optimizely-agent/index.md | 2 +- .../050 - api-reference.md | 2 +- .../060 - github-repository.md | 2 +- 16 files changed, 42 insertions(+), 28 deletions(-) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md index a17a19d0..ecc4455f 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/001 - AUTHOR-AGENT-DOCS-IN-GITHUB.md @@ -4,7 +4,7 @@ excerpt: "" slug: "author-agent-docs-in-github" hidden: true createdAt: "2020-02-21T17:44:53.019Z" -updatedAt: "2020-04-13T23:02:34.056Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Agent docs sync from Github. So, any changes you author here in Readme will just be overwritten. Make docs updates over in Github. For more info, see [authoring guidelines in github](https://github.com/optimizely/agent/blob/master/docs/internal%20docs%20authoring%20notes.md). diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md index 5bdadc3c..13779717 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/010 - optimizely-agent.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Optimizely Agent microservice - Optimizely Full Stack" createdAt: "2020-02-21T20:35:58.387Z" -updatedAt: "2020-07-14T20:51:52.458Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Optimizely Agent is a standalone, open-source, and highly available microservice that provides major benefits over using Optimizely SDKs in certain use cases. The [Agent REST API](https://library.optimizely.com/docs/api/agent/v1/index.html) offers consolidated and simplified endpoints for accessing all the functionality of Optimizely Full Stack SDKs. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index 0d2991b6..0cc35128 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Quickstart for Agent - Optimizely Full Stack" createdAt: "2020-05-21T20:35:58.387Z" -updatedAt: "2020-08-17T20:51:52.458Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- This brief quickstart describes how to run Agent, using two examples: @@ -73,13 +73,18 @@ for key in env['featuresMap']: ### Run a feature flag rule -The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule and flag variation the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. ```python params = { "keys": "my-feature-flag" } -payload = { "userId": "test-user" } +payload = { + "userId": "test-user", + "userAttributes": { + "attr1": "sample-attribute-1", + "attr2": "sample-attribute-2" + } +} resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md index 23de9d44..d71d59ed 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/020 - setup-optimizely-agent.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Install Agent - Optimizely Full Stack" createdAt: "2020-02-21T17:44:27.363Z" -updatedAt: "2020-03-31T23:54:17.841Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- ## Running Agent from source (Linux / OSX) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md index d975d560..6628abee 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/010 - evaluate-rest-apis.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Evaluate REST APIs - Optimizely Full Stack" createdAt: "2020-02-21T17:44:53.019Z" -updatedAt: "2020-04-13T23:02:34.056Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Below is an example demonstrating the APIs capabilities. For brevity, we've chosen to illustrate the API usage with Python. Note that the API documentation is defined via an OpenAPI (Swagger) spec and can be viewed [here](https://library.optimizely.com/docs/api/agent/v1/index.htm). @@ -44,7 +44,14 @@ To run a flag rule, use ```python # decide 1 flag. params = { "keys": "my-feature-flag" } -payload = { "userId": "test-user" } +payload = { + "userId": "test-user", + "userAttributes": { + "attr1": "sample-attribute-1", + "attr2": "sample-attribute-2" + } +} + resp = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload) print(resp.json()) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md index 9aefdfba..ed571c5a 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/020 - admin-api.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Admin APIs - Optimizely Full Stack" createdAt: "2020-02-21T17:44:28.054Z" -updatedAt: "2020-02-21T23:09:19.274Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- The Admin API provides system information about the running process. This can be used to check the availability of the service, runtime information and operational metrics. By default the admin listener is configured on port 8088. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 5be6bc6c..05ff01de 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "How to use Optimizely Agent - Optimizely Full Stack" createdAt: "2020-02-21T17:44:28.054Z" -updatedAt: "2020-04-08T21:26:30.308Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Optimizely Agent provides [APIs](https://library.optimizely.com/docs/api/agent/v1/index.html) that enable running feature flag rules, such as A/B tests and targeted flag deliveries. Agent provides equivalent functionality to all our SDKs. At its core is the [Optimizely Go SDK](doc:go-sdk). @@ -18,22 +18,24 @@ The Decide [endpoint](https://library.optimizely.com/docs/api/agent/v1/index.htm `POST /v1/decide?keys={flagKey}` -In the request `application/json` body, include the `userID` and any `decideOptions`. The full request looks like this: +In the request `application/json` body, include the `userId` and any `decideOptions`. The full request looks like this: ```curl -curl --request POST 'http://localhost:8080/v1/decide' \ ---header 'Content-Type: application/json' \ ---header 'X-Optimizely-SDK-Key: ' \ ---header 'Content-Type: application/json' \ +curl --location --request POST 'http://localhost:8080/v1/decide?keys=YOUR_FLAG_1&keys=YOUR_FLAG_2' +--header 'X-Optimizely-SDK-Key: YOUR_SDK_KEY' +--header 'Accept: text/event-stream' +--header 'Content-Type: application/json' --data-raw '{ -"userId": "test-user" "decideOptions": [ - "INCLUDE_REASONS" -] +], +"userId": "string", +"userAttributes": { +"additionalProp1": {} +} }' ``` -TODO: please review above and below request/response examples, I didn't test them, just looked at the Pull request for decide and made some guesses!! -FE + diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md index df731365..b3429cd5 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Agent Authorization - Optimizely Full Stack" createdAt: "2020-03-11T20:58:11.777Z" -updatedAt: "2020-03-31T19:44:52.119Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Optimizely Agent supports authorization workflows based on OAuth and JWT standards, allowing you to protect access to its API and Admin interfaces. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md index cbd14cb3..18b063fe 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Agent microservice webhooks - Optimizely Full Stack" createdAt: "2020-02-21T17:44:26.981Z" -updatedAt: "2020-05-05T17:03:48.045Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Optimizely Agent implements a webhook listener used to receive inbound [Webhook](doc:configure-webhooks) requests from optimizely.com. These webhooks enable PUSH style notifications triggering immediate project configuration updates. The webhook listener is configured on its own port (default: 8085) since it can be configured to select traffic from the internet. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md index fa5b3605..966dc9d9 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/030 - docker-configurations.md @@ -4,6 +4,6 @@ excerpt: "" slug: "docker-configurations" hidden: true createdAt: "2020-03-13T18:37:48.448Z" -updatedAt: "2020-03-13T18:37:48.448Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Stub page for further info on how to configure docker? \ No newline at end of file diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md index f986333b..f993df86 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Agent notifications - Optimizely Full Stack" createdAt: "2020-05-21T20:35:58.387Z" -updatedAt: "2020-07-14T20:51:52.458Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- Agent provides an endpoint that sends notifications to subscribers via [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). This is Agent's equivalent of Notification Listeners found in Optimizely SDKs. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md index 24e30804..7c3f9864 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "advanced config - Agent microservice - Optimizely Full Stack" createdAt: "2020-05-21T20:35:58.387Z" -updatedAt: "2020-07-14T20:51:52.458Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- ## Setting Configuration Values diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md index db908946..08e0c15d 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/050 - agent-plugins.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Agent plugins - Optimizely Full Stack" createdAt: "2020-09-21T20:30:00.000Z" -updatedAt: "2020-09-21T20:30:00.000Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- ## Agent Plugins diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md index d4f936f0..e748038e 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/040 - configure-optimizely-agent/index.md @@ -6,7 +6,7 @@ hidden: false metadata: title: "Configure Agent microservice - Optimizely Full Stack" createdAt: "2020-02-21T17:44:27.173Z" -updatedAt: "2020-04-08T21:42:08.698Z" +updatedAt: "2021-03-15T23:02:34.056Z" --- By default Optimizely Agent uses the configuration file in the current active directory, e.g., `./config.yaml`. You can override the [default configuration](https://github.com/optimizely/agent/blob/master/config.yaml) by providing a yaml configuration file at runtime. diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md index 152953a7..1f1c3c91 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/050 - api-reference.md @@ -4,7 +4,7 @@ excerpt: "" slug: "api-reference" hidden: false createdAt: "2020-02-21T17:44:52.492Z" -updatedAt: "2020-02-21T17:44:52.492Z" +updatedAt: "2021-03-15T23:02:34.056Z" type: "link" link_url: "https://library.optimizely.com/docs/api/agent/v1/index.html" link_external: true diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md index ae341515..f0b36a5c 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/060 - github-repository.md @@ -4,7 +4,7 @@ excerpt: "" slug: "github-repository" hidden: false createdAt: "2020-02-21T17:44:28.559Z" -updatedAt: "2020-02-21T17:44:28.559Z" +updatedAt: "2021-03-15T23:02:34.056Z" type: "link" link_url: "https://github.com/optimizely/agent" link_external: true From 286f73904b5c513baac0031dcf14cba5645ee926 Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:54:44 -0600 Subject: [PATCH 10/11] Update 012 - quickstart-for-agent.md --- .../v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md index 0cc35128..643778fd 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/012 - quickstart-for-agent.md @@ -73,6 +73,7 @@ for key in env['featuresMap']: ### Run a feature flag rule +The `/decide?keys={keys}` endpoint decides whether to enable a feature flag or flags for a given user. You can decide multiple flags with this syntax: `/v1/decide?keys=flagA&keys=flagB`. We'll provide a `userId` via the request body. The API evaluates the `userId` to determine which flag rule and flag variation the user buckets into. Rule types include A/B tests, in which flag variations are measured against one another, or a flag delivery, which progressively make the flag available to the selected audience. This endpoint returns an array of `OptimizelyDecision` objects, which contains information about the flag and rule the user bucketed into. From 3ea755d25e37a48beab482794a57a6b95a2e529e Mon Sep 17 00:00:00 2001 From: fscelliott <42477011+fscelliott@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:59:49 -0600 Subject: [PATCH 11/11] removed todo --- .../deploy-as-a-microservice/030 - use-optimizely-agent/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md index 05ff01de..242bf24b 100644 --- a/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md +++ b/docs/readme-sync/v4.0/deploy-as-a-microservice/030 - use-optimizely-agent/index.md @@ -82,7 +82,6 @@ To authenticate, [pass your SDK key](https://docs.developers.optimizely.com/ful - To get decisions for multiple keys, specify multiple keys parameters, for example: `keys=flag_key_1&keys=flag_key_2` - TODO: is above example right? - To receive only the enabled feature flags for a visitor use a decide option in the `application/json` request body: