From 9357931b06c660c3c66571f5430648988e7a06fd Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 21 Jul 2025 13:55:41 -0400 Subject: [PATCH 1/3] draft of customize method names --- .../sdks/guides/customize-method-names.mdx | 88 +++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/fern/products/sdks/guides/customize-method-names.mdx b/fern/products/sdks/guides/customize-method-names.mdx index 2faae4b6c..8a0255677 100644 --- a/fern/products/sdks/guides/customize-method-names.mdx +++ b/fern/products/sdks/guides/customize-method-names.mdx @@ -3,9 +3,11 @@ title: Customize Method Names description: Fine-tune SDK resources and method names --- -Fern allows you to fine-tune your SDK method and group names so that -your SDK reads exactly how you want it to. For example, instead of -`client.postUsers` you can configure the SDK to read `client.users.create()`. +You can fine-tune your SDK method and group names to create intuitive, readable +code that matches your API's purpose. + +For example, instead of `client.postUsers` +you can configure the SDK to read `client.users.create()`. @@ -64,10 +66,86 @@ endpoints under an `admin` group, the SDK would then read: See how merge.dev uses nested groups [here](https://github.com/merge-api/merge-node-client?tab=readme-ov-file#create-link-token). + + + +Directly specify the method names within your service structure. + +```yaml title="api.yaml" +services: + http: + UsersService: + base-path: /users # specify the base path + endpoints: + create: # configure SDK method name + method: POST + path: "" +``` + +produces the same client.users.create() method + + + +You can customize your SDK method names in two ways: + +* **Let Fern parse `operationId` (automatic):** By default, Fern uses your + operation ID to generate method names. Format your operation IDs like + `{tag_name}_{operation_name}` (e.g., `users_get`) and Fern will automatically + generate `users.get()`. If your operation ID doesn't start with a tag, Fern + uses it directly as the method name. + +* **Use the `x-fern-sdk-group-name` and `x-fern-sdk-method-name`extensions to + explicitly define your method name and grouping (e.g., + `x-fern-sdk-method-name: users.get`). + + +In the example below, Fern will generate a method called `client.users.create()` for the `POST /users` endpoint. + +```yaml title="openapi.yml" +paths: + /users: + post: + x-fern-sdk-group-name: users + x-fern-sdk-method-name: create +``` + +## Top level methods + +If you omit the `x-fern-sdk-group-name` extension, then the generated SDK method will live at the root. +In the example below, Fern will generate a method called `client.send()`: + +```yaml title="openapi.yaml" +paths: + /send: + post: + x-fern-sdk-method-name: send +``` + +## Multiple levels of nesting + +If you add more than one `x-fern-sdk-group-name` extension, then the generated SDK will nest group names. +The order of the group names is preserved in the generated SDK method. + +In the example below, Fern will generate a method called `client.users.notifications.send()`: + +```yaml title="openapi.yaml" +paths: + /users/notifications: + post: + x-fern-sdk-group-name: + - users + - notifications + x-fern-sdk-method-name: send +``` + + + If you're using an OpenAPI Specification, you'll need to leverage the [`x-fern-sdk-method-name`](/learn/api-definition/openapi/extensions#sdk-method-names) extension. If you're using the fern definition, then the method name comes from the endpoint directly. ## Casing -Additionally, Fern handles choosing the appropriate casing for each SDK -language: `snake_case` in python, `camelCase` in TypeScript and `PascalCase` in Go, etc. +Fern handles choosing the appropriate casing for each SDK +language: `snake_case` in python, `camelCase` in TypeScript and `PascalCase` in + Go, etc. Because of this, you define the endpoint structure once and get + properly formatted methods across all generated SDKs. From 248c193c7ba00c13040774c9170759f9cbe36084 Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 21 Jul 2025 16:50:54 -0400 Subject: [PATCH 2/3] updates to method names doc --- .../sdks/guides/customize-method-names.mdx | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/fern/products/sdks/guides/customize-method-names.mdx b/fern/products/sdks/guides/customize-method-names.mdx index 8a0255677..65a9b2901 100644 --- a/fern/products/sdks/guides/customize-method-names.mdx +++ b/fern/products/sdks/guides/customize-method-names.mdx @@ -3,11 +3,11 @@ title: Customize Method Names description: Fine-tune SDK resources and method names --- -You can fine-tune your SDK method and group names to create intuitive, readable +You can fine-tune your SDK method and group names to create intuitive, user-friendly code that matches your API's purpose. For example, instead of `client.postUsers` -you can configure the SDK to read `client.users.create()`. +you can configure your SDK to read `client.users.create()`. @@ -34,6 +34,8 @@ you can configure the SDK to read `client.users.create()`. +## Nesting groups + Groups can also be arbitrarily nested. For example, if you want to nest the `users` endpoints under an `admin` group, the SDK would then read: @@ -62,6 +64,7 @@ endpoints under an `admin` group, the SDK would then read: + See how merge.dev uses nested groups [here](https://github.com/merge-api/merge-node-client?tab=readme-ov-file#create-link-token). @@ -69,23 +72,29 @@ See how merge.dev uses nested groups [here](https://github.com/merge-api/merge-n -Directly specify the method names within your service structure. +## Configure custom method names in `api.yml` + + For a Fern Definition, the method name comes from the endpoint directly. + You can specify group and method names directly within your service structure. + +In the example below, Fern will generate a method called `client.users.create()`: -```yaml title="api.yaml" +```yaml title="api.yaml" {4, 6} services: http: - UsersService: - base-path: /users # specify the base path + UsersService: # specify the group + base-path: /users # HTTP path endpoints: create: # configure SDK method name method: POST path: "" ``` -produces the same client.users.create() method +## Configure custom method names in `openapi.yaml` + You can customize your SDK method names in two ways: * **Let Fern parse `operationId` (automatic):** By default, Fern uses your @@ -94,14 +103,14 @@ You can customize your SDK method names in two ways: generate `users.get()`. If your operation ID doesn't start with a tag, Fern uses it directly as the method name. -* **Use the `x-fern-sdk-group-name` and `x-fern-sdk-method-name`extensions to - explicitly define your method name and grouping (e.g., - `x-fern-sdk-method-name: users.get`). - +* **Use the `x-fern-sdk-group-name` and `x-fern-sdk-method-name` extensions + (manual)** to explicitly define your method name and grouping. -In the example below, Fern will generate a method called `client.users.create()` for the `POST /users` endpoint. +To manually configure your method name, use the `x-fern-sdk-group-name` and +`x-fern-sdk-method-name` extensions. In the example below, Fern will generate a +method called `client.users.create()` for the `POST /users` endpoint. -```yaml title="openapi.yml" +```yaml title="openapi.yml" {4-5} paths: /users: post: @@ -111,10 +120,11 @@ paths: ## Top level methods -If you omit the `x-fern-sdk-group-name` extension, then the generated SDK method will live at the root. +If you omit the `x-fern-sdk-group-name` extension, then the generated SDK method +will live at the root of the client rather than nested under a resource group. In the example below, Fern will generate a method called `client.send()`: -```yaml title="openapi.yaml" +```yaml title="openapi.yaml" {4} paths: /send: post: @@ -140,12 +150,9 @@ paths: -If you're using an OpenAPI Specification, you'll need to leverage the [`x-fern-sdk-method-name`](/learn/api-definition/openapi/extensions#sdk-method-names) -extension. If you're using the fern definition, then the method name comes from the endpoint directly. - -## Casing +## Casing is automatically configured -Fern handles choosing the appropriate casing for each SDK +Fern automatically handles choosing the appropriate casing for each SDK language: `snake_case` in python, `camelCase` in TypeScript and `PascalCase` in Go, etc. Because of this, you define the endpoint structure once and get properly formatted methods across all generated SDKs. From 7de7f48fa65550560c0b74e633427dd9704f71ef Mon Sep 17 00:00:00 2001 From: Devin Logan Date: Mon, 21 Jul 2025 17:03:06 -0400 Subject: [PATCH 3/3] additional edits to intro par --- .../sdks/guides/customize-method-names.mdx | 120 +++++++++--------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/fern/products/sdks/guides/customize-method-names.mdx b/fern/products/sdks/guides/customize-method-names.mdx index 65a9b2901..45aa1a7f3 100644 --- a/fern/products/sdks/guides/customize-method-names.mdx +++ b/fern/products/sdks/guides/customize-method-names.mdx @@ -9,65 +9,7 @@ code that matches your API's purpose. For example, instead of `client.postUsers` you can configure your SDK to read `client.users.create()`. - - - ```ts - const response = await client.users.create(); - ``` - - - ```python - response = client.users.create() - # or async - response = await async_client.users.create() - ``` - - - ```java - const response = client.users().create(); - ``` - - - ```go - const response = client.Users.Create(); - ``` - - - -## Nesting groups - -Groups can also be arbitrarily nested. For example, if you want to nest the `users` -endpoints under an `admin` group, the SDK would then read: - - - - ```ts - const response = await client.admin.users.create(); - ``` - - - ```python - response = client.admin.users.create() - # or async - response = await async_client.admin.users.create() - ``` - - - ```java - const response = client.admin().users().create(); - ``` - - - ```go - const response = client.Admin.Users.Create(); - ``` - - - - - -See how merge.dev uses nested groups [here](https://github.com/merge-api/merge-node-client?tab=readme-ov-file#create-link-token). - +This page covers how to customize method and group names using Fern Definition and OpenAPI specs. @@ -133,6 +75,10 @@ paths: ## Multiple levels of nesting + +See how merge.dev uses nested groups [here](https://github.com/merge-api/merge-node-client?tab=readme-ov-file#create-link-token). + + If you add more than one `x-fern-sdk-group-name` extension, then the generated SDK will nest group names. The order of the group names is preserved in the generated SDK method. @@ -156,3 +102,59 @@ Fern automatically handles choosing the appropriate casing for each SDK language: `snake_case` in python, `camelCase` in TypeScript and `PascalCase` in Go, etc. Because of this, you define the endpoint structure once and get properly formatted methods across all generated SDKs. + +## Generated SDK examples + +Here's how developers using your generated SDK would call the customized method names in their applications: + + + + ```ts + const response = await client.users.create(); + ``` + + + ```python + response = client.users.create() + # or async + response = await async_client.users.create() + ``` + + + ```java + const response = client.users().create(); + ``` + + + ```go + const response = client.Users.Create(); + ``` + + + +Here's how users would call nested groups: + + + + ```ts + const response = await client.admin.users.create(); + ``` + + + ```python + response = client.admin.users.create() + # or async + response = await async_client.admin.users.create() + ``` + + + ```java + const response = client.admin().users().create(); + ``` + + + ```go + const response = client.Admin.Users.Create(); + ``` + +