From 14e052b9ac7a7ee01cc03e77c96ab694c0bb4e01 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 13 Jan 2023 12:40:28 +0100 Subject: [PATCH] docs: auto-generate remaining server-side SDK docs (#2858) This PR builds on the preceding doc auto-generation PRs and generates documentation for the remaining server-side SDKs. ## Why Refer to https://github.com/Unleash/unleash/pull/2809 for more context about generating SDK docs. ## What - Adds generation for the remaining server-side SDKs - Moves generated docs from the `/reference/sdks` directory to `/generated` directory. - Makes sure that the URLs do not change because of the move by using the `slug` frontmatter property. - replaces relative github links in the markdown documents so that they become absolute github links. (refer to the next section) - Updates some image styling so that it doesn't apply to readme badges (we don't need them using `display: block`) ### On link replacing: This PR adds handling of links in the generated documentation. Specifically, it changes links in one case: Relative links to github. Links to code and other files in the repository. These are prefixed with the repository's URL. While this should work in most cases, it will fail in cases where the links to the files are not on the repository's primary branch. (typically main, but could also be "v3", for instance). In these cases, the links will get a double branch in the URL and will fail. However, I see no easy way around this (though suggestions are definitely accepted!), and think it's a fair tradeoff. It takes the links from "definitely failing" to "will work in the vast majority of cases". Note: I originally also wanted to handle the case where the link is an absolute link to docs.getunleash.io. We could turn these into relative urls to avoid full page reloads and enjoy a smoother experience. However, the client-side redirects don't work correctly if the relative URL goes to a redirect page, so you end up with a 404 page. As such, I think it's better to leave the links as absolute for now. --- .gitignore | 7 +- .../how-to/how-to-use-custom-strategies.md | 2 +- website/docs/reference/sdks/dotnet.md | 116 ----------------- website/docs/reference/sdks/index.md | 18 +-- website/docs/reference/sdks/java.md | 121 ------------------ website/docs/reference/sdks/node.md | 98 -------------- website/docs/reference/sdks/php.md | 100 --------------- website/docs/reference/sdks/python.md | 76 ----------- website/docs/reference/sdks/ruby.md | 65 ---------- .../docs/topics/the-anatomy-of-unleash.mdx | 2 +- website/docusaurus.config.js | 2 +- website/readme-fns.js | 88 +++++++++++-- website/sidebars.js | 12 +- website/src/css/custom.css | 6 +- 14 files changed, 100 insertions(+), 613 deletions(-) delete mode 100644 website/docs/reference/sdks/dotnet.md delete mode 100644 website/docs/reference/sdks/java.md delete mode 100644 website/docs/reference/sdks/node.md delete mode 100644 website/docs/reference/sdks/php.md delete mode 100644 website/docs/reference/sdks/python.md delete mode 100644 website/docs/reference/sdks/ruby.md diff --git a/.gitignore b/.gitignore index 4721527221..6b7a71fe6d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ lerna-debug npm-debug .DS_Store /dist -website/docs/reference/api/**/sidebar.js # Logs logs @@ -51,4 +50,8 @@ package-lock.json /website/i18n/* .env -#report.json \ No newline at end of file +#report.json + +# Generated docs +website/docs/reference/api/**/sidebar.js +website/docs/generated diff --git a/website/docs/how-to/how-to-use-custom-strategies.md b/website/docs/how-to/how-to-use-custom-strategies.md index c52b5b4115..44a96f1164 100644 --- a/website/docs/how-to/how-to-use-custom-strategies.md +++ b/website/docs/how-to/how-to-use-custom-strategies.md @@ -31,7 +31,7 @@ The steps to implement a custom strategy for your client depend on the kind of c ### Option A: Implement the strategy for a server-side client SDK {#step-3-a} -1. **Implement the custom strategy** in your [client SDK](../reference/sdks/index.md). The exact way to do this will vary depending on the specific SDK you're using, so refer to the SDK's documentation. The example below shows an example of how you'd implement a custom strategy called "TimeStamp" for the [Node.js client SDK](../reference/sdks/node.md). +1. **Implement the custom strategy** in your [client SDK](../reference/sdks/index.md). The exact way to do this will vary depending on the specific SDK you're using, so refer to the SDK's documentation. The example below shows an example of how you'd implement a custom strategy called "TimeStamp" for the [Node.js client SDK](/docs/generated/sdks/server-side/node.md). ```js const { Strategy } = require('unleash-client'); diff --git a/website/docs/reference/sdks/dotnet.md b/website/docs/reference/sdks/dotnet.md deleted file mode 100644 index 2962765a22..0000000000 --- a/website/docs/reference/sdks/dotnet.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: .NET SDK ---- - -import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - -In this guide we explain how to use feature toggles in a .NET application using Unleash-hosted. We will be using the open source Unleash [.net Client SDK](https://github.com/Unleash/unleash-client-dotnet). - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens.mdx) - -## Step 1: Install client SDK {#step-1-install-client-sdk} - -First we must add Unleash Client SDK as a dependency to your project. Below is an example of how you would add it via the .NET cli. Please see [NuGet](https://www.nuget.org/packages/Unleash.Client/) for other alternatives. - -```sh -dotnet add package unleash.client -``` - -## Step 2: Create a new Unleash Instance {#step-2-create-a-new-unleash-instance} - -Next we must initialize a new instance of the Unleash Client. - -:::tip Synchronous initialization - -By default, the client SDK asynchronously fetches toggles from the Unleash API on initialization. This means it can take a few hundred milliseconds for the client to reach the correct state. - -You can use the `synchronousInitialization` option of the `UnleashClientFactory` class's `CreateClientAsync` method to block the client until it has successfully synced with the server. See the following "synchronous initialization" code sample. - -Read more about the [Unleash architecture](https://www.getunleash.io/blog/our-unique-architecture) to learn how it works. - -::: - - - - -```csharp -var settings = new UnleashSettings() -{ - AppName = "dot-net-client", - Environment = "local", - UnleashApi = new Uri("API URL"), - CustomHttpHeaders = new Dictionary() - { - {"Authorization","API token" } - } -}; - -IUnleash unleash = new DefaultUnleash(settings); -``` - - - - -```csharp -var settings = new UnleashSettings() -{ - AppName = "dot-net-client", - Environment = "local", - UnleashApi = new Uri("API URL"), - CustomHttpHeaders = new Dictionary() - { - {"Authorization","API token" } - } -}; - -var unleashFactory = new UnleashClientFactory(); - -// this `unleash` will fetch feature toggles and write them to its cache before returning from the await call. -// if network errors or disk permissions prevent this from happening, the await will throw an exception. -IUnleash unleash = await unleashFactory.CreateClientAsync(settings, synchronousInitialization: true); -``` - - - - -In your app you typically just want one instance of Unleash, and inject that where you need it. - -You should change the URL and the Authorization header (API token) with the correct values for your instance, which you may locate under “Instance admin” in the menu. - -## Step 3: Use the feature toggle {#step-3-use-the-feature-toggle} - -Now that we have initialized the client SDK we can start using feature toggles defined in Unleash in our application. To achieve this we have the “isEnabled” method available, which will allow us to check the value of a feature toggle. This method will return true or false based on whether the feature should be enabled or disabled for the current request. - -```csharp -if (unleash.IsEnabled("Demo")) -{ - //do some magic -} -else -{ - //do old boring stuff -} -``` - -## Step 4: Provide Unleash Context {#step-4-provide-unleash-context} - -It is the client SDK that computes whether a feature toggle should be considered enabled or disabled for specific use request. This is the job of the activation strategies, which are implemented in the client SDK. - -The activation strategies is an implementation of rules based on data, which you provide as part of the Unleash Context. - -**a) As argument to the isEnabled call** - -The simplest way to provide the Unleash Context is as part of the “isEnabled” call: - -```csharp -var context = new UnleashContext -{ - UserId = "61" -}; - -unleash.IsEnabled("someToggle", context); -``` - -b) Via a UnleashContextProvider - -This is a bit more advanced approach, where you configure an unleash-context provider. By doing this, you do not have to rebuild or to pass the unleash-context object to every place you are calling `unleash.IsEnabled`. You can read more, and get [examples about this option on GitHub](https://github.com/Unleash/unleash-client-dotnet#unleashcontextprovider). diff --git a/website/docs/reference/sdks/index.md b/website/docs/reference/sdks/index.md index f68f3e98d6..cdbf3fad4b 100644 --- a/website/docs/reference/sdks/index.md +++ b/website/docs/reference/sdks/index.md @@ -12,14 +12,14 @@ Unleash provides official client SDKs for a number of programming language. Addi Server-side clients run on your server and communicate directly with your Unleash instance. We provide these official clients: -- [Go SDK](go.md) -- [Java SDK](java.md) -- [Node.js SDK](node.md) -- [PHP SDK](php.md) -- [Python SDK](python.md) -- [Ruby SDK](ruby.md) -- [Rust SDK](https://github.com/unleash/unleash-client-rust) -- [.NET SDK](dotnet.md) +- [Go SDK](/docs/generated/sdks/server-side/go.md) +- [Java SDK](/docs/generated/sdks/server-side/java.md) +- [Node.js SDK](/docs/generated/sdks/server-side/node.md) +- [PHP SDK](/docs/generated/sdks/server-side/php.md) +- [Python SDK](/docs/generated/sdks/server-side/python.md) +- [Ruby SDK](/docs/generated/sdks/server-side/ruby.md) +- [Rust SDK](/docs/generated/sdks/server-side/rust.md) +- [.NET SDK](/docs/generated/sdks/server-side/dotnet.md) ### Client-side SDKs @@ -51,7 +51,7 @@ If you see an item marked with a ❌ that you would find useful, feel free to re ::: -| Capability | [Java](/reference/sdks/java.md) | [Node.js](/reference/sdks/node.md) | [Go](/reference/sdks/go.md) | [Python](/reference/sdks/python.md) | [Ruby](/reference/sdks/ruby.md) | [.NET](/reference/sdks/dotnet) | [PHP](/reference/sdks/php.md) | [Rust](https://github.com/unleash/unleash-client-rust) | [Unleash Proxy](/reference/unleash-proxy.md) | +| Capability | [Java](/docs/generated/sdks/server-side/java.md) | [Node.js](/docs/generated/sdks/server-side/node.md) | [Go](/docs/generated/sdks/server-side/go.md) | [Python](/docs/generated/sdks/server-side/python.md) | [Ruby](/docs/generated/sdks/server-side/ruby.md) | [.NET](/docs/generated/sdks/server-side/dotnet.md) | [PHP](/docs/generated/sdks/server-side/php.md) | [Rust](/docs/generated/sdks/server-side/rust.md) | [Unleash Proxy](/reference/unleash-proxy.md) | | --- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | **Category: Initialization** | | | | | | | | | | | Async initialization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | N/A | diff --git a/website/docs/reference/sdks/java.md b/website/docs/reference/sdks/java.md deleted file mode 100644 index 2fba80ed7d..0000000000 --- a/website/docs/reference/sdks/java.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Java SDK ---- - -import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - -In this guide we explain how to use feature toggles in a Java application using Unleash-hosted. We will be using the open source Unleash [Java Client SDK](https://github.com/Unleash/unleash-client-java). - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens) - -## Step 1: Install the client SDK {#step-1-install-the-client-sdk} - -First we must add Unleash Client SDK as a dependency to your project. Below is an example of how you would add it to your pom.xml in Java: - -```xml - - io.getunleash - unleash-client-java - Latest version here - -``` - -## Step 2: Create a new Unleash Instance {#step-2-create-a-new-unleash-instance} - -Next we must initialize a new instance of the Unleash Client. - -:::tip Synchronous initialization - -The client SDK will synchronize with the Unleash API on initialization, so it can take a few hundred milliseconds for the client to reach the correct state. You can use the `synchronousFetchOnInitialisation` option to block the client until it has successfully synced with the server. - -::: - - - - -```java -UnleashConfig config = UnleashConfig.builder() - .appName("my.java-app") - .instanceId("your-instance-1") - .environment(System.getenv("APP_ENV")) - .unleashAPI("API URL") - .customHttpHeader("Authorization", "API token") - .build(); - -Unleash unleash = new DefaultUnleash(config); -``` - - - - -```java -UnleashConfig config = UnleashConfig.builder() - .appName("my.java-app") - .instanceId("your-instance-1") - .environment(System.getenv("APP_ENV")) - .unleashAPI("API URL") - .customHttpHeader("Authorization", "API token") - .synchronousFetchOnInitialization(true) - .build(); - -Unleash unleash = new DefaultUnleash(config); -``` - - - - -In your app you typically just want one instance of Unleash, and inject that where you need it. You will typically use a dependency injection frameworks such as Spring or Guice to manage this. - -You should change the URL and the Authorization header (API token) with the correct values for your instance, which you may locate under “Instance admin” in the menu. - -## Step 3: Use the feature toggle {#step-3-use-the-feature-toggle} - -Now that we have initialized the client SDK we can start using feature toggles defined in Unleash in our application. To achieve this we have the “isEnabled” method available, which will allow us to check the value of a feature toggle. This method will return **true** or **false** based on whether the feature should be enabled or disabled for the current request. - -```java -if(unleash.isEnabled("AwesomeFeature")) { - //do some magic -} else { - //do old boring stuff -} -``` - -Read more about the [Unleash architecture](https://www.unleash-hosted.com/articles/our-unique-architecture) to learn how it works in more details - -## Step 4: Provide Unleash Context {#step-4-provide-unleash-context} - -It is the client SDK that computes whether a feature toggle should be considered enabled or disabled for specific use request. This is the job of the [activation strategies](../../reference/activation-strategies.md), which are implemented in the client SDK. - -The activation strategies is an implementation of rules based on data, which you provide as part of the Unleash Context. - -**a) As argument to the isEnabled call** - -The simplest way to provide the Unleash Context is as part of the “isEnabled” call: - -```java -UnleashContext context = UnleashContext.builder() - .userId("user@mail.com").build(); - -unleash.isEnabled("someToggle", context); -``` - -**b) Via a UnleashContextProvider** - -This is a bit more advanced approach, where you configure a unleash-context provider. By doing this you do not have to rebuild or to pass the unleash-context object to every place you are calling `unleash.isEnabled`. - -The provider typically binds the context to the same thread as the request. If you are using Spring the UnleashContextProvider will typically be a ‘request scoped’ bean. - -```java -UnleashContextProvider contextProvider = new MyAwesomeContextProvider(); -UnleashConfig config = new UnleashConfig.Builder() - .appName("java-test") - .instanceId("instance x") - .unleashAPI("https://unleash.example.com/api/") - .unleashContextProvider(contextProvider) - .build(); - -Unleash unleash = new DefaultUnleash(config); - -// Anywhere in the code unleash will get the unleash context from your registered provider. -unleash.isEnabled("someToggle"); -``` diff --git a/website/docs/reference/sdks/node.md b/website/docs/reference/sdks/node.md deleted file mode 100644 index d62fed25c9..0000000000 --- a/website/docs/reference/sdks/node.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Node SDK ---- - -import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - -In this guide we explain how to use feature toggles in a Node application using Unleash-hosted. We will be using the open source Unleash [Node.js Client SDK](https://github.com/Unleash/unleash-client-node). - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens.mdx) - -## Step 1: Install the client SDK {#step-1-install-the-client-sdk} - -First we must install Node.js dependency: - -```shell npm2yarn -npm install unleash-client -``` - -## Step 2: Initialize the client SDK {#step-2-initialize-the-client-sdk} - -Next we must initialize the client SDK in the application: - -:::tip Synchronous initialization - -The client SDK will synchronize with the Unleash API on initialization, so it can take a few hundred milliseconds for the client to reach the correct state. - -See the following code sample or the [_block until Unleash is synchronized_ section of the readme](https://github.com/Unleash/unleash-client-node#block-until-unleash-sdk-has-synchronized) for the steps to do this. - -::: - - - - -```js -const unleash = require('unleash-client'); - -unleash.initialize({ - url: 'https://YOUR-API-URL', - appName: 'my-node-name', - customHeaders: { Authorization: 'SOME-SECRET' }, -}); -``` - - - - -```js -const { startUnleash } = require('unleash-client'); - -const unleash = await startUnleash({ - url: 'https://YOUR-API-URL', - appName: 'my-node-name', - customHeaders: { Authorization: 'SOME-SECRET' }, -}); -``` - - - - -The example code above will initialize the client SDK, and try to connect to the Unleash instance you point it to. You will need to use your own Unleash instance URL and a [server-side API token](../api-tokens-and-client-keys.mdx#client-tokens) to connect. For steps on how to create an API token, refer to the [_how to create API tokens_](../../how-to/how-to-create-api-tokens.mdx) guide. - -## Step 3: Use the feature toggle {#step-3-use-the-feature-toggle} - -Now that we have initialized the client SDK in our application we can start using feature toggles defined in Unleash in our application. To achieve this we have the “isEnabled” method available, which will allow us to check the value of a feature toggle. This method will return **true** or **false** based on whether the feature should be enabled or disabled for the current request. - -```javascript -setInterval(() => { - if (unleash.isEnabled('DemoToggle')) { - console.log('Toggle enabled'); - } else { - console.log('Toggle disabled'); - } -}, 1000); -``` - -Please note that in the above example we put the isEnabled-evaluation inside the setInterval method. This is required in the small example to make sure that the feature toggle is not evaluated, and application exits, before the client SDK have been able to synchronize with the Unleash-hosted API. State is kept in memory by the client SDK (and synchronizes with the Unleash-hosted API in the background). This is done to prefer performance over update speed. You can read more about the [Unleash architecture](https://www.unleash-hosted.com/articles/our-unique-architecture). - -It can also be nice to notice that if you use an undefined feature toggle the Unleash SDK will return false instead of crashing your application. The SDK will also report metrics back to Unleash-hosted on feature toggle usage, which makes it \_possible to spot toggles not yet defined. And this is a very neat way to help you debug if something does not work as expected. - -_Note that you can also wait until the Unleash SDK has fully synchronized similar to familiar "on-ready" hooks in other APIs. See [block until Unleashed is synchronized](https://github.com/Unleash/unleash-client-node#block-until-unleash-sdk-has-synchronized) for how to do this._ - -## Step 4: Provide the Unleash-context {#step-4-provide-the-unleash-context} - -It is the client SDK that computes whether a feature toggle should be considered enabled or disabled for a specific request. This is the job of the activation strategies, which are implemented in the client SDK. - -An activation strategy is an implementation of rules based on data, which you provide as part of the Unleash Context. - -You provide the Unleash context as part of the second argument to the isEnabled call: - -```javascript -const context = { - userId: '123', - sessionId: '123123-123-123', - remoteAddress: '127.0.0.1', -}; - -const enabled = isEnabled('app.demo', context); -``` diff --git a/website/docs/reference/sdks/php.md b/website/docs/reference/sdks/php.md deleted file mode 100644 index 9d38c706da..0000000000 --- a/website/docs/reference/sdks/php.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: PHP SDK ---- - -In this guide we explain how to use feature toggles in a PHP application using Unleash-hosted. We will be using the open source Unleash [PHP Client SDK](https://github.com/Unleash/unleash-client-php). - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens) - -## Step 1: Install the client SDK {#step-1-install-the-client-sdk} - -First we must add Unleash Client SDK as a dependency to your project. Below is an example of how to install it via composer: - -```shell -composer require unleash/client guzzlehttp/guzzle symfony/cache -``` - -> Note: You can install any other PSR-16, PSR-17 and PSR-18 implementations instead of guzzlehttp/guzzle and symfony/cache - -## Step 2: Create a new Unleash Instance {#step-2-create-a-new-unleash-instance} - -Next we must initialize a new instance of the Unleash Client. - -```php -withAppName('my.php-app') - ->withInstanceId('your-instance-1') - ->withAppUrl('API URL') - ->withHeader('Authorization', 'API token') - ->build(); -``` - -In your app you typically just want one instance of Unleash, and inject that where you need it. You will typically use a dependency injection frameworks to manage this. - -You should change the URL and the Authorization header (API token) with the correct values for your instance, which you may locate under “Instance admin” in the menu. - -## Step 3: Use the feature toggle {#step-3-use-the-feature-toggle} - -Now that we have initialized the client SDK we can start using feature toggles defined in Unleash in our application. To achieve this we have the “isEnabled” method available, which will allow us to check the value of a feature toggle. This method will return **true** or **false** based on whether the feature should be enabled or disabled for the current request. - -```php -isEnabled("AwesomeFeature")) { - //do some magic -} else { - //do old boring stuff -} -``` - -Read more about the [Unleash architecture](https://www.unleash-hosted.com/articles/our-unique-architecture) to learn how it works in more details - -## Step 4: Provide Unleash Context {#step-4-provide-unleash-context} - -It is the client SDK that computes whether a feature toggle should be considered enabled or disabled for specific use request. This is the job of the [activation strategies](../../reference/activation-strategies.md), which are implemented in the client SDK. - -The activation strategies is an implementation of rules based on data, which you provide as part of the Unleash Context. - -**a) As argument to the isEnabled call** - -The simplest way to provide the Unleash Context is as part of the “isEnabled” call: - -```php -isEnabled("someToggle", $context); -``` - - -**b) Via a UnleashContextProvider** - -This is a bit more advanced approach, where you configure a unleash-context provider. By doing this you do not have to rebuild or to pass the unleash-context object to every place you are calling `$unleash->isEnabled()`. - -```php -withAppName('my.php-app') - ->withInstanceId('your-instance-1') - ->withAppUrl('https://unleash.example.com/api/') - ->withContextProvider($contextProvider) - ->build(); - -// Anywhere in the code unleash will get the unleash context from your registered provider. -$unleash->isEnabled("someToggle"); -``` - -> You can read more complete documentation in the [Client SDK repository](https://github.com/Unleash/unleash-client-php). diff --git a/website/docs/reference/sdks/python.md b/website/docs/reference/sdks/python.md deleted file mode 100644 index 9d34804b2c..0000000000 --- a/website/docs/reference/sdks/python.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Python SDK ---- - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens.mdx) - -```python -from UnleashClient import UnleashClient - -client = UnleashClient( - url="", - app_name="my-python-app", - custom_headers={'Authorization': ''}) - -client.initialize_client() - -client.is_enabled("unleash.beta.variants") -``` - -## Checking if a feature is enabled {#checking-if-a-feature-is-enabled} - -Check a feature's status: - -```Python title="Check whether a feature is enabled" -client.is_enabled("my_toggle") -``` - -To supply application context, use the second positional argument: - -```Python title="Check whether a feature is enabled for the given context" -app_context = {"userId": "test@email.com"} -client.is_enabled("user_id_toggle", app_context) -``` - -### Fallback function and default values - -You can specify a fallback function for cases where the client doesn't recognize the toggle by using the `fallback_function` keyword argument: - -```Python title="Check a feature status, using a fallback if the feature is unrecognized." -def custom_fallback(feature_name: str, context: dict) -> bool: - return True - -client.is_enabled("my_toggle", fallback_function=custom_fallback) -``` - -You can also use the `fallback_function` argument to replace the obsolete `default_value` keyword argument by using a lambda that ignores its inputs. Whatever the lambda returns will be used as the default value. - -```Python title="Use fallback_function to provide a default value" -client.is_enabled("my_toggle", fallback_function=lambda feature_name, context: True) -``` - -The fallback function **must** accept the feature name and context as positional arguments in that order. - -The client will evaluate the fallback function only if an exception occurs when calling the `is_enabled()` method. This happens when the client can't find the feature flag. The client _may_ also throw other, general exceptions. - -## Getting a variant {#getting-a-variant} - -Checking for a variant: - -```python -context = {'userId': '2'} # Context must have userId, sessionId, or remoteAddr. If none are present, distribution will be random. - -variant = client.get_variant("my_variant_toggle", context) - -print(variant) -> { -> "name": "variant1", -> "payload": { -> "type": "string", -> "value": "val1" -> }, -> "enabled": True -> } -``` - -Read more at [github.com/Unleash/unleash-client-python](https://github.com/Unleash/unleash-client-python) diff --git a/website/docs/reference/sdks/ruby.md b/website/docs/reference/sdks/ruby.md deleted file mode 100644 index 4032b49160..0000000000 --- a/website/docs/reference/sdks/ruby.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Ruby SDK ---- - -> You will need your `API URL` and your `API token` in order to connect the Client SDK to you Unleash instance. You can find this information in the “Admin” section Unleash management UI. [Read more](../../how-to/how-to-create-api-tokens.mdx) - -```ruby -require 'unleash' - -@unleash = Unleash::Client.new( - url: '', - app_name: 'simple-test', - custom_http_headers: {'Authorization': ''}, -) -``` - -### Sample usage {#sample-usage} - -To evaluate a feature toggle, you can use: - -```ruby -if @unleash.is_enabled? "AwesomeFeature", @unleash_context - puts "AwesomeFeature is enabled" -end -``` - -If the feature is not found in the server, it will by default return false. However you can override that by setting the default return value to `true`: - -```ruby -if @unleash.is_enabled? "AwesomeFeature", @unleash_context, true - puts "AwesomeFeature is enabled by default" -end -``` - -Alternatively by using `if_enabled` you can send a code block to be executed as a parameter: - -```ruby -@unleash.if_enabled "AwesomeFeature", @unleash_context, true do - puts "AwesomeFeature is enabled by default" -end -``` - -### Variations {#variations} - -If no variant is found in the server, use the fallback variant. - -```ruby -fallback_variant = Unleash::Variant.new(name: 'default', enabled: true, payload: {"color" => "blue"}) -variant = @unleash.get_variant "ColorVariants", @unleash_context, fallback_variant - -puts "variant color is: #{variant.payload.fetch('color')}" -``` - -## Client methods {#client-methods} - -| Method Name | Description | Return Type | -| --- | --- | --- | -| `is_enabled?` | Check if feature toggle is to be enabled or not. | Boolean | -| `enabled?` | Alias to the `is_enabled?` method. But more ruby idiomatic. | Boolean | -| `if_enabled` | Run a code block, if a feature is enabled. | `yield` | -| `get_variant` | Get variant for a given feature | `Unleash::Variant` | -| `shutdown` | Save metrics to disk, flush metrics to server, and then kill ToggleFetcher and MetricsReporter threads. A safe shutdown. Not really useful in long running applications, like web applications. | nil | -| `shutdown!` | Kill ToggleFetcher and MetricsReporter threads immediately. | nil | - -Read more at [github.com/Unleash/unleash-client-ruby](https://github.com/Unleash/unleash-client-ruby) diff --git a/website/docs/topics/the-anatomy-of-unleash.mdx b/website/docs/topics/the-anatomy-of-unleash.mdx index b047804476..fdabbe45cd 100644 --- a/website/docs/topics/the-anatomy-of-unleash.mdx +++ b/website/docs/topics/the-anatomy-of-unleash.mdx @@ -156,7 +156,7 @@ Because you’d like to see the new color scheme while you’re developing it, y You configure an [Unleash SDK for your server](../reference/sdks/index.md) to communicate with Unleash. When rendering the page, you check the state of the new-color-scheme feature and render a different stylesheet based on the results. -In pseudocode (loosely based on the [Node.js SDK](../reference/sdks/node.md)), that might look like this: +In pseudocode (loosely based on the [Node.js SDK](/docs/generated/sdks/server-side/node.md)), that might look like this: ```js if (unleash.isEnabled(“new-color-scheme”)) { diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 53553b8086..ea40a7e5ad 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -603,7 +603,7 @@ module.exports = { // more info at https://github.com/rdilweb/docusaurus-plugin-remote-content#options name: 'content-sdks', sourceBaseUrl: 'https://raw.githubusercontent.com/Unleash/', // gets prepended to all of the documents when fetching - outDir: 'docs/reference/sdks', // the base directory to output to. + outDir: 'docs/generated/sdks', // the base directory to output to. documents: readmes.documentUrls, // the file names to download modifyContent: readmes.modifyContent, }, diff --git a/website/readme-fns.js b/website/readme-fns.js index b8358e6bd9..5f6264ca77 100644 --- a/website/readme-fns.js +++ b/website/readme-fns.js @@ -15,14 +15,33 @@ // type ReadmeData = Readme & { repoUrl: string }; // all SDK repos and what they map to for the sidebar. -const SDKS = { +const sdksUnmapped = { 'unleash-client-go': { sidebarName: 'Go', branch: 'v3', }, + 'unleash-client-java': { + sidebarName: 'Java', + }, + 'unleash-client-node': { + sidebarName: 'Node', + }, + 'unleash-client-php': { + sidebarName: 'PHP', + }, + 'unleash-client-python': { + sidebarName: 'Python', + }, + 'unleash-client-ruby': { + sidebarName: 'Ruby', + }, 'unleash-client-rust': { sidebarName: 'Rust', }, + 'unleash-client-dotnet': { + sidebarName: '.NET', + slugName: 'dotnet', + }, // 'unleash-android-proxy-sdk': { // sidebarName: 'Android', @@ -30,35 +49,78 @@ const SDKS = { // }, }; +const SDKS = Object.fromEntries( + Object.entries(sdksUnmapped).map(([repoName, repoData]) => { + const repoUrl = `https://github.com/Unleash/${repoName}`; + const slugName = ( + repoData.slugName ?? repoData.sidebarName + ).toLowerCase(); + const branch = repoData.branch ?? 'main'; + + return [repoName, { ...repoData, repoUrl, slugName, branch }]; + }), +); + function getReadmeRepoData(filename) { const repoName = filename.split('/')[0]; const repoData = SDKS[repoName]; - const repoUrl = `https://github.com/Unleash/${repoName}`; - - if (repoData) { - return { - repoUrl, - ...repoData, - slugName: (repoData.slugName ?? repoData.sidebarName).toLowerCase(), - }; - } else return { sidebarName: repoName, repoUrl }; + return repoData; } const documentUrls = Object.entries(SDKS).map( - ([repo, { branch = 'main' }]) => `${repo}/${branch ?? 'main'}/README.md`, + ([repo, { branch }]) => `${repo}/${branch}/README.md`, ); +// Replace links in the incoming readme content. +// +// There's one cases we want to handle: +// +// 1. Relative links that point to the repo. These must be prefixed with the +// link to the github repo. +// +// Note: You might be tempted to handle absolute links to docs.getunleash.io and +// make them relative. While absolute links will work, they trigger full page +// refreshes. Relative links give a slightly smoother user experience. +// +// However, if the old link goes to a redirect, then the client-side redirect +// will not kick in, so you'll end up with a "Page not found". +const replaceLinks = ({ content, repo }) => { + const markdownLink = /(?<=\[.*\]\(\s?)([^\s\)]+)(?=.*\))/g; + + const replacer = (url) => { + try { + // This constructor will throw if the URL is relative. + // https://developer.mozilla.org/en-US/docs/Web/API/URL/URL + const parsedUrl = new URL(url); + + return url; + } catch { + // case 1 + if (url.startsWith('#')) { + // ignore links to other doc sections + return url; + } else { + const separator = url.startsWith('/') ? '' : '/'; + return `${repo.url}/blob/${repo.branch}${separator}${url}`; + } + } + }; + + return content.replaceAll(markdownLink, replacer); +}; + const modifyContent = (filename, content) => { const sdk = getReadmeRepoData(filename); const generationTime = new Date(); return { - filename: `${sdk.slugName}.md`, + filename: `server-side/${sdk.slugName}.md`, content: `--- title: ${sdk.sidebarName} SDK +slug: /reference/sdks/${sdk.slugName} --- :::info Generated content @@ -71,7 +133,7 @@ This document was generated from the README in the [${ To connect to Unleash, you'll need your Unleash API url (e.g. \`https:///api\`) and a [server-side API token](/reference/api-tokens-and-client-keys.mdx#client-tokens) ([how do I create an API token?](/how-to/how-to-create-api-tokens.mdx)). ::: -${content} +${replaceLinks({ content, repo: { url: sdk.repoUrl, branch: sdk.branch } })} --- diff --git a/website/sidebars.js b/website/sidebars.js index f33f07be22..4a4bd2f871 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -232,14 +232,10 @@ module.exports = { type: 'category', label: 'Server-side SDKs', items: [ - 'reference/sdks/go', - 'reference/sdks/java', - 'reference/sdks/node', - 'reference/sdks/php', - 'reference/sdks/python', - 'reference/sdks/ruby', - 'reference/sdks/rust', - 'reference/sdks/dotnet', + { + type: 'autogenerated', + dirName: 'generated/sdks/server-side', + }, ], }, { diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 4087699ef2..9919f41ac7 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -88,12 +88,14 @@ main img { box-shadow: var(--ifm-global-shadow-lw); } -main p > img { +main p > img:not([src^="https://img.shields.io/" i], [src*="badge.svg?branch=" i]) +{ /* give inline images a border */ border: var(--ifm-global-border-width) solid var(--unleash-color-gray); } -main :is(p, figure) > img { +main :is(p, figure) > img:not([src^="https://img.shields.io/" i], [src*="badge.svg?branch=" i]) +{ /* round corners to match the rest of the page */ border-radius: var(--ifm-global-radius);