Giter Club home page Giter Club logo

fern's Introduction


Fern is a toolkit that allows you to input your API Definition and output SDKs and API documentation. Fern is compatible with the OpenAPI specification (formerly Swagger).

Overview Diagram

๐ŸŒฟ SDKs

The Fern toolkit is available via a command line interface (CLI) and requires Node 18+. To install it, run:

npm install -g fern-api

Initialize Fern with your OpenAPI spec:

fern init --openapi ./path/to/openapi.yml
# or
fern init --openapi https://link.buildwithfern.com/petstore-openapi

Your directory should look like the following:

fern/
โ”œโ”€ fern.config.json
โ”œโ”€ generators.yml # generators you're using
โ””โ”€ openapi/
  โ””โ”€ openapi.json # your openapi document

Finally, to invoke the generator, run:

fern generate

๐ŸŽ‰ Once the command completes, you'll see your SDK in /generated/sdks/typescript.

๐ŸŒฟ API Documentation

Fern can also build and host a documentation website with an auto-generated API reference. Write additional pages in markdown and have them versioned with git. Search, SEO, dark mode, and popular components are provided out-of-the-box. Plus, you can customize the colors, font, logo, and domain name.

Check out docs built with Fern:

Get started here.

๐ŸŒฟ Generators

Generators are process that take your API Definition as input and output artifacts (SDKs, Postman Collections, Server boilerplate, etc.). To add a generator run fern add <generator id>

SDK Generators

Generator ID Latest Version Changelog Entrypoint
fernapi/fern-typescript-node-sdk Typescript Generator Version CHANGELOG.md cli.ts
fernapi/fern-python-sdk Python Generator Version CHANGELOG.md cli.py
fernapi/fern-java-sdk Java Generator Version CHANGELOG.md Cli.java
fernapi/fern-ruby-sdk Ruby Generator Version CHANGELOG.md cli.ts
fernapi/fern-go-sdk Go Generator Version CHANGELOG.md main.go
fernapi/fern-csharp-sdk C# Generator Version CHANGELOG.md cli.ts

Server-side Generators

Fern's server-side generators output boilerplate application code (models and networking logic). This is intended for spec-first or API-first developers, who write their API definition (as an OpenAPI spec or Fern definition) and want to generate backend code. Watch a demo here.

Generator ID Latest Version Changelog Entrypoint
fernapi/fern-typescript-express Typescript Express Server Generator Version CHANGELOG.md cli.ts
fernapi/fern-fastapi-server Python FastAPI Server Generator Version CHANGELOG.md cli.py
fernapi/fern-java-spring Java Spring Server Generator Version CHANGELOG.md Cli.java

Model Generators

Fern's model generators will output schemas or types defined in your OpenAPI spec or Fern Definition.

Generator ID Latest Version Changelog Entrypoint
fernapi/fern-pydantic-model Pydantic Model Generator Version CHANGELOG.md cli.py
fernapi/java-model Java Model Generator Version CHANGELOG.md Cli.java
fernapi/fern-ruby-model Ruby Model Generator Version CHANGELOG.md cli.ts

Spec Generators

Fern's spec generators can output an OpenAPI spec or a Postman collection.

Note: The OpenAPI spec generator is primarly intended for Fern Definition users. This prevents lock-in so that one can always export to OpenAPI.

Generator ID Latest Version Changelog Entrypoint
fernapi/fern-openapi OpenAPI Generator Version CHANGELOG.md cli.ts
fernapi/fern-postman Postman Generator Version CHANGELOG.md cli.ts

๐ŸŒฟ CLI Commands

Here's a quick look at the most popular CLI commands. View the documentation for all CLI commands.

fern init: adds a new starter API to your repository.

fern check: validate your API definition and Fern configuration.

fern generate: run the generators specified in generators.yml in the cloud.

fern generate --local: run the generators specified in generators.yml in docker locally.

fern add <generator>: include a new generator in your generators.yml. For example, fern add fern-python-sdk.

Advanced

API First

Fern supports developers and teams that want to be API-first or Spec-first.

Define your API, and use Fern to generate models, networking code and boilerplate application code. The generated code adds type safety to your API implementation - if your backend doesn't implement the API correctly, it won't compile.

Frameworks currently supported:

For a walkthrough, check out the Fern + Express video.

Fern Definition

While we are big fans of OpenAPI, we know it isn't the easiest format to read and write. If you're looking for an alternative, give the Fern Definition a try.

Install the Fern CLI and initialize a Fern Project.

npm install -g fern-api
fern init

This will create the following folder structure in your project:

fern/
โ”œโ”€ fern.config.json # root-level configuration
โ”œโ”€ generators.yml # generators you're using
โ””โ”€ definition/
  โ”œโ”€ api.yml  # API-level configuration
  โ””โ”€ imdb.yml # endpoints, types, and errors

Here's what the imdb.yml starter file looks like:

types:
  MovieId: string

  Movie:
    properties:
      id: MovieId
      title: string
      rating:
        type: double
        docs: The rating scale is one to five stars

  CreateMovieRequest:
    properties:
      title: string
      rating: double

service:
  auth: false
  base-path: /movies
  endpoints:
    createMovie:
      docs: Add a movie to the database
      method: POST
      path: /create-movie
      request: CreateMovieRequest
      response: MovieId

    getMovie:
      method: GET
      path: /{movieId}
      path-parameters:
        movieId: MovieId
      response: Movie
      errors:
        - MovieDoesNotExistError

errors:
  MovieDoesNotExistError:
    status-code: 404
    type: MovieId

Checkout open source projects that are using Fern Definitions:

Community

Join our Discord! We are here to answer questions and help you get the most out of Fern.

Contributing

We welcome community contributions. For guidelines, refer to our CONTRIBUTING.md.

Fern Contributors

fern's People

Contributors

abvthecity avatar aevitas avatar amckinney avatar armandobelardo avatar atwooddc avatar bsinghvi avatar chdeskur avatar codebender828 avatar connormahon34 avatar dannysheridan avatar davidkonigsberg avatar dcb6 avatar dependabot[bot] avatar dsinghvi avatar franklinharvey avatar gfxkai avatar jmedway614 avatar jochs avatar kafkas avatar minaelee avatar mscolnick avatar omarrida avatar ppod1991 avatar rishan10 avatar sahil485 avatar sk-sam avatar swimburger avatar teisjayaswal avatar tjb9dc avatar zachkirsch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fern's Issues

[Feature] Pagination in SDKs

The generated SDK should make it very easy to 1/ iterate over all pages, 2/ ask simple questions like .is_next_page_available(). In order to do this the Fern Definition must understand what the pagination scheme is.

Simplify http config

DayOfWeekService:
      auth: none
      endpoints:
        getCurrentDayOfWeek:
          method: GET
          path: /day-of-week
          response: DayOfWeek

Our opinion is that many devs will don't actually care about the method or path of the endpoint as long as they can declare inputs and outputs.

Fern should support devs not specifying method or path. It can default method to POST and path to the endpoint id. This provides the flexibility to integrate existing APIs while allowing devs to iterate faster on their APIs by reducing config required.

Adding validation

Creating issue where we can jot down all validations we have to add:

Support for reusing query parameters

@dannysheridan encountered a case where a set of endpoints take the same 10 query-params. It's annoying to copy paste them everywhere and changing one things requires you to make edits in n different places.

Should we have a concept of grouped query params?

Add support for websockets

It should be really easy for the FE to subscribe to "topics", and easy for the backend to send those updates to each FE

Rename parameters to path-parameters

I think the yaml is cleaner when it reads like

storeTracedWorkspaceV2:
        http: POST /store-workspace-trace-v2/submission/{submissionId}
        path-parameters:
          submissionId: submission.SubmissionId
        query-parameters:
          stuff: Stuff
        body: list<submission.TraceResponseV2>

as opposed to

storeTracedWorkspaceV2:
        http: POST /store-workspace-trace-v2/submission/{submissionId}
        parameters:
          submissionId: submission.SubmissionId
        query-parameters:
          stuff: Stuff
        body: list<submission.TraceResponseV2>

Best practice for organizing objects

What are the best practices about where to put objects relative to each other?

How ought a dev organize their objects as they relate to their services? I think the first object mentioned in Services should be the first listed in Objects. The second object mentioned in Services should be the second in Objects, and so on.

Could we encode the best practices in a linter or validation?

fern generate runs only one generator

fern generate --name would run that generator. The problem is that you can have the same generator multiple times so how do you differentiate across those?

Support non-alphabetic enum values

Enums should have a name and value field. If the enums are alphanumeric then value defaults to name, but if not then name needs to be specified so that codegen can be done properly.

Metrics for endpoints

I want to know:

  • Which endpoints are being hit the most?
  • Size of request/responses
  • Histogrammable & filterable errors

Other:

  • Rate limiting
  • SLA management

Validation: Only objects are allowed to be extended

It doesn't make sense to extend union, enum, or an alias because it is unclear what the extended type would look like (i.e. why would I ever extend a union instead of adding it as a field).
We should validate that only objects are allowed to be extended.

Fern visualize

It would be cool if fern visualize would fire up a local ui where you can edit and changes are written back to your yaml files.
No code UI at the edge

Example spec

Add an example spec to the Fern repo. It should include Rest + Websockets.

Store exact union type shape in the IR

The rules for the wire format are a little tricky (depending on if the unioned type is an object or not). Better to encode this in the IR than to do it correctly in each plugin.

RequestId/MessageId

@zachkirsch i think every wire message should have an id that makes it very easy to trace through your api while debugging. The IDs have been invaluable in my experience and fern is in a great position to bake them in.

Can see us building a self-hostable analytics tool on top that can track those IDs and make it very easy for PMs + Devs to understand metrics/filter.

Fern validate CLI

A command-line command of fern validate that takes my YML and checks for mistakes/errors before I run fern generate

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.