diff --git a/fern/docs.yml b/fern/docs.yml index 14f245b7303..c2dbb75a3d9 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -31,6 +31,9 @@ tabs: display-name: SDKs icon: fa-brands fa-codepen slug: sdks + servers: + display-name: Server Stubs + slug: servers cli-api: display-name: CLI & API Reference icon: fa-regular fa-code @@ -385,14 +388,26 @@ navigation: path: ./pages/docs/components/endpoint-response-snippet.mdx icon: "turn-down" slug: response-snippet - - section: Alternatives hidden: true contents: - page: ReadMe slug: readme path: ./pages/docs/comparison/readme.mdx - + - tab: servers + layout: + - section: Introduction + contents: + - page: What is server code generation? + path: ./pages/servers/introduction.mdx + - section: Server Frameworks + contents: + - page: Express server + path: ./pages/servers/express.mdx + - page: FastAPI server + path: ./pages/servers/fastapi.mdx + - page: Spring server + path: ./pages/servers/spring.mdx - tab: cli-api layout: - section: CLI Reference diff --git a/fern/pages/servers/express.mdx b/fern/pages/servers/express.mdx new file mode 100644 index 00000000000..a902782d568 --- /dev/null +++ b/fern/pages/servers/express.mdx @@ -0,0 +1,143 @@ +--- +title: Express Server +description: Generate Express Node.js server code from an API specification including OpenAPI, Swagger, AsyncAPI, and Fern Definition. +subtite: Generate types and networking logic for your Node.js Express server. +slug: express +--- + +Express is a minimal and flexible Node.js web application framework. It is a popular choice for building APIs and web servers. + +Fern generates TypeScript types and networking logic for your Express server. This saves you time and adds compile-time safety by guaranteeing that you are serving the exact API that you specified in your API definition. + +## What Fern generates + +- TypeScript interfaces for your API types +- Exceptions that you can throw for non-200 responses +- Interfaces for you to define your business logic +- All the networking/HTTP logic to call your API + +## Use the starter repository + +Clone the [starter repo](https://github.com/fern-api/express-starter/) for Express + React. + +## Demo video + +Learn how Fern can be helpful when building an Express server. + +
+ +## Getting started + + + +### Define your API + +Define your API using the [OpenAPI Specification](/learn/api-definition/openapi/overview) or the [Fern Definition](/learn/api-definition/fern/overview). + +### Add the Express generator + +Add the Express server generator to your `generators.yml` file. + + +```yaml +groups: + express-server: + generators: + - name: fernapi/fern-typescript-express + version: 0.15.0 + output: + location: local-file-system + path: ../app/server +``` + + +### +Run the [CLI](/learn/cli-api/cli-reference/cli-overview) command `fern generate --group express-server`. + +Make sure to enable `allowSyntheticDefaultImports` in your `tsconfig.json` when using this generator. + +### Implement the functions + +Provide the business logic by implementing each function. For example, if we were implenting the IMDb API, we would implement the `get_movie` function. + + +```python +from .generated.fern import AbstractMoviesService, Movie, MovieDoesNotExistError, MovieId + +class MoviesService(AbstractMoviesService): + def get_movie(self, *, movie_id: str) -> Movie: + if movie_id == "titanic": + return Movie( + id=MovieId.from_str("titantic"), + title="Titanic", + rating=9.8, + ) + raise MovieDoesNotExistError(MovieId.from_str(movie_id)) +``` + + +### Run the server + +```bash +poetry run start +``` + +### Call the API 🚀 + +```bash +$ curl --location --request GET --silent 'localhost:8080/movies/titanic' | jq . +{ + "id": "titantic", + "title": "Titanic", + "rating": 9.8 +} + +$ curl --location --request GET --silent 'localhost:8080/movies/oceans-11' | jq . +{ + "error": "MovieDoesNotExistError", + "errorInstanceId": "f6e1d69c-bf97-42d5-bc89-5e42773e3880", + "content": "oceans-11" +} +``` + + + +## Advanced Configurations + +Tailor the `config` of the Express server generator to your needs. The default values for all options are `false`. + +| Configuration Option | Description | +| -------------------- | ----------- | +| `useBrandedStringAliases` | When `true`, string aliases are generated as branded strings. This makes each alias feel like its own type and improves compile-time safety. | +| `areImplementationsOptional` | | +| `doNotHandleUnrecognizedErrors` | | +| `includeUtilsOnUnionMembers` | | +| `includeOtherInUnionTypes` | | +| `treatUnknownAsAny` | When `true`, unknown types at runtime are generated into TypeScript using the `any` type. | +| `noSerdeLayer` | Allows you to control whether (de-)serialization code is generated. When true, the client uses JSON.parse() and JSON.stringify() instead.
By default, the generated client includes a layer for serializing requests and deserializing responses. This has three benefits:
1. The client validates requests and response at runtime, client-side.
2. The client can support complex types, like Date and Set.
3. The generated types can stray from the wire/JSON representation to be more idiomatic. For example, when `noSerdeLayer` is disabled, all properties are camelCase, even if the server is expecting snake_case. | +| `skipRequestValidation` | | +| `skipResponseValidation` | By default, this config is set to `false` and the client will throw an error if the response from the server doesn't match the expected type (based on how the response is modeled in the API definition). Set this config to `true` to never throw an error if the response is misshapen. Rather, the client will log the issue using console.warn and return the data (cast to the expected response type). | +| `outputEsm` | Allows you to control whether the generated TypeScript targets `CommonJS` or `esnext`. By default, the generated TypeScript targets `CommonJS`. | +| `outputSourceFiles` | When `false` (default), the generator outputs .js and d.ts files. When `true`, the generator outputs raw TypeScript files. | +| `retainOriginalCasing` | | +| `allowExtraFields` | | + +The configuration options are accessible in [`ExpressCustomConfig.ts`](https://github.com/fern-api/fern/blob/main/generators/typescript/express/cli/src/custom-config/ExpressCustomConfig.ts). + +### Example Configuration + + +```diff +groups: + express-server: + generators: + - name: fernapi/fern-typescript-express + version: 0.15.0 + output: + location: local-file-system + path: ../app/server ++ config: ++ useBrandedStringAliases: true ++ noSerdeLayer: true +``` + \ No newline at end of file diff --git a/fern/pages/servers/fastapi.mdx b/fern/pages/servers/fastapi.mdx new file mode 100644 index 00000000000..20cdf5a537b --- /dev/null +++ b/fern/pages/servers/fastapi.mdx @@ -0,0 +1,133 @@ +--- +title: FastAPI Server +description: Generate FastAPI server code from an API specification including OpenAPI, Swagger, AsyncAPI, and Fern Definition. +subtite: Generate types and networking logic for your Python FastAPI server. +slug: fastapi +--- + +FastAPI is a modern, fast web framework for building APIs with Python based on standard Python type hints. It is a popular choice for building APIs and web servers. + +Fern outputs types and networking logic for your FastAPI server. This saves you time and adds compile-time safety by guaranteeing that you are serving the exact API that you specified in your API definition. + +## What Fern generates + +- Pydantic models for your API types +- Exceptions that you can throw for non-200 responses +- Abstract classes for you to define your business logic +- All the networking/HTTP logic to call your API + +## Use the starter repository + +Clone the [starter repo](https://github.com/fern-api/fastapi-starter/) for FastAPI + React. + +## Demo video + +Learn how Fern can be helpful when building a FastAPI server. + +
+ +## Getting started + + + +### Define your API + +Define your API using the [OpenAPI Specification](/learn/api-definition/openapi/overview) or the [Fern Definition](/learn/api-definition/fern/overview). + +### Add the FastAPI generator + +Add the FastAPI server generator to your `generators.yml` file. + + +```yaml +groups: + fastapi-server: + generators: + - name: fernapi/fern-fastapi-server + version: 0.9.3 + output: + location: local-file-system + path: ../app/server +``` + + +### Generate code + +Run the [CLI](/learn/cli-api/cli-reference/cli-overview) command `fern generate --group fastapi-server`. + +### Implement the functions + +Provide the business logic by implementing each function. For example, if we were implenting the IMDb API, we would implement the `get_movie` function. + + +```python +from .generated.fern import AbstractMoviesService, Movie, MovieDoesNotExistError, MovieId + +class MoviesService(AbstractMoviesService): + def get_movie(self, *, movie_id: str) -> Movie: + if movie_id == "titanic": + return Movie( + id=MovieId.from_str("titantic"), + title="Titanic", + rating=9.8, + ) + raise MovieDoesNotExistError(MovieId.from_str(movie_id)) +``` + + +### Run the server + +```bash +poetry run start +``` + +### Call the API 🚀 + +```bash +$ curl --location --request GET --silent 'localhost:8080/movies/titanic' | jq . +{ + "id": "titantic", + "title": "Titanic", + "rating": 9.8 +} + +$ curl --location --request GET --silent 'localhost:8080/movies/oceans-11' | jq . +{ + "error": "MovieDoesNotExistError", + "errorInstanceId": "f6e1d69c-bf97-42d5-bc89-5e42773e3880", + "content": "oceans-11" +} +``` + + + +## Advanced Configurations + +Tailor the `config` of the FastAPI server generator to your needs. The default values for all options are `false`. + +| Configuration Option | Description | +| -------------------- | ----------- | +| `include_validators` | | +| `skip_formatting` | | +| `async_handlers` | | + +The configuration options are accessible in [`custom_config.py`](https://github.com/fern-api/fern/blob/main/generators/python/src/fern_python/generators/fastapi/custom_config.py). + +### Example Configuration + + +```diff +groups: + fastapi-server: + generators: + - name: fernapi/fern-fastapi-server + version: 0.9.3 + output: + location: local-file-system + path: ../app/server ++ config: ++ include_validators: true ++ skip_formatting: true ++ async_handlers: true +``` + diff --git a/fern/pages/servers/introduction.mdx b/fern/pages/servers/introduction.mdx new file mode 100644 index 00000000000..dd57288c48e --- /dev/null +++ b/fern/pages/servers/introduction.mdx @@ -0,0 +1,22 @@ +--- +title: What is Server Code Generation? +description: Generate server boilerplate code from an API specification including OpenAPI, Swagger, AsyncAPI, and Fern Definition. +subtite: Generate types and networking logic for your server framework of choice. +slug: server-codegen +--- + +Fern's server-side generators output boilerplate application code that includes models and networking logic. This is intended for API First developers, who write their API definition before building their app. Fern supports generating backend code from an OpenAPI specification or Fern Definition. + +## Supported server frameworks + +- Node.js [Express](/learn/express) +- Python [FastAPI](/learn/fastapi) +- Java [Spring Boot](/learn/spring) + +Want to request a new server framework? [Let us know](https://github.com/fern-api/fern/issues/new?assignees=&labels=&projects=&template=feature-request.md&title=%5BFeature%5D). + +## Why use Fern for server code generation? + +1. **Save time**: generate boilerplate code instead of writing it. +1. **Compile-time safety**: get validation that your endpoints are being served correctly. +1. **Develop API-first**: design your API contract before you start building your app. Pick the best server framework for the job. \ No newline at end of file diff --git a/fern/pages/servers/spring.mdx b/fern/pages/servers/spring.mdx new file mode 100644 index 00000000000..60535914b9d --- /dev/null +++ b/fern/pages/servers/spring.mdx @@ -0,0 +1,119 @@ +--- +title: Spring Server +description: Generate Spring Boot server code from an API specification including OpenAPI, Swagger, AsyncAPI, and Fern Definition. +subtite: Generate types and networking logic for your Java Spring Boot server. +slug: spring +--- + +Spring Boot is a popular Java framework for building APIs and web servers. It is a framework widely used in the Java community. + +Fern outputs types and networking logic for your Spring Boot server. This saves you time and adds compile-time safety by guaranteeing that you are serving the exact API that you specified in your API definition. + +## What Fern generates + +- Java classes for your API types +- Exceptions that you can throw for non-200 responses +- Abstract classes for you to define your business logic +- All the networking/HTTP logic to call your API + +## Use the starter repository + +Clone the [starter repo](https://github.com/fern-api/spring-starter/) for Spring + React. + +## Demo video + +Learn how Fern can be helpful when building a Spring server. + +
+ +## Getting started + + + +### Define your API + +Define your API using the [OpenAPI Specification](/learn/api-definition/openapi/overview) or the [Fern Definition](/learn/api-definition/fern/overview). + +### Add the Spring generator + +Add the Spring server generator to your `generators.yml` file. + + +```yaml +groups: + spring-server: + generators: + - name: fernapi/fern-java-spring + version: 0.8.3 + output: + location: local-file-system + path: ../app/server +``` + + +### Generate code + +Run the [CLI](/learn/cli-api/cli-reference/cli-overview) command `fern generate --group spring-server`. + +### Implement the functions + +Provide the business logic by implementing each function. + +### Run the server + +```bash +// if using Maven +$ mvn spring-boot:run + +// if using Gradle +$ gradle bootRun +``` + +### Call the API 🚀 + +```bash +$ curl --location --request GET --silent 'localhost:8080/movies/titanic' | jq . +{ + "id": "titantic", + "title": "Titanic", + "rating": 9.8 +} + +$ curl --location --request GET --silent 'localhost:8080/movies/oceans-11' | jq . +{ + "error": "MovieDoesNotExistError", + "errorInstanceId": "f6e1d69c-bf97-42d5-bc89-5e42773e3880", + "content": "oceans-11" +} +``` + + + +## Advanced Configurations + +Tailor the `config` of the Spring Boot server generator to your needs. + +| Configuration Option | Description | +| -------------------- | ----------- | +| `wrappedAliases`| | +| `enablePublicConstructors` | | + +The configuration options are accessible in [`SpringCustomConfig.java`](https://github.com/fern-api/fern/blob/main/generators/java/spring/src/main/java/com/fern/java/spring/SpringCustomConfig.java). + +### Example Configuration + + +```diff +groups: + spring-server: + generators: + - name: fernapi/fern-java-spring + version: 0.8.3 + output: + location: local-file-system + path: ../app/server ++ config: ++ wrappedAliases: false ++ enablePublicConstructors: true +``` + \ No newline at end of file diff --git a/fern/pages/welcome.mdx b/fern/pages/welcome.mdx index 2512c1c2a8c..46c32144026 100644 --- a/fern/pages/welcome.mdx +++ b/fern/pages/welcome.mdx @@ -8,15 +8,19 @@ hide-toc: true Our entire docs website (the one you're looking at right now!) is built using Fern. [See the source markdown.](https://github.com/fern-api/fern/blob/main/fern/pages/welcome.mdx) +APIs underpin the internet but are still painful to work with. They are often untyped, unstandardized, and out-of-sync across multiple sources of truth. + +Fern is a developer tool designed to generate SDKs, documentation, and servers from an API definition. Build with Fern to offer easy-to-use and well-documented APIs. + ## Products - Start with an API Definition + Idiomatic client libraries - Idiomatic client libraries + Generate server-side code ## Motivation
- Stripe, Twilio, and AWS have the resources to invest in internal tooling for developer - experience. They provide client libraries in multiple languages and developer documentation - that stays up-to-date. + Stripe, Twilio, and AWS have the resources to invest in internal tooling for developer experience. They provide client libraries in multiple languages and developer documentation that stays up-to-date. We are building Fern to productize this process and make it accessible to all software companies. @@ -55,6 +57,12 @@ hide-toc: true +## Go API First +Fern allows developers to design their API before building their app. This approach is known as `API First Development` and allows teams to iterate on their API design before writing any code. Use Fern to generate server code, SDKs, and documentation from your API definition. +If you're starting from scratch, we recommend you start with the Fern Definition. Think of it as _OpenAPI simple_. +Fern supports the following inputs +- [OpenAPI (formerly Swagger)](/learn/api-definition/openapi/overview) +- [Fern Definition](/learn/api-definition/fern/overview)