Code-First GraphQL API Development
Dive into Pylon effortlessly with our streamlined guide, helping you set up your development environment and embark on your journey to building powerful web services.
Installation
Get started with Pylon in minutes.
Core concepts
Learn about the fundamental concepts of Pylon.
Integrations
Explore how Pylon integrates with databases and other tools.
Contributing
Contribute to the Pylon project and help make it better.
Quick start
This "Quick Start" page provides a step-by-step guide for new users to quickly set up and begin using Pylon, with sections for installing dependencies, creating a new project, starting the development server, building for production, and deploying to production.
Installing dependencies
To get started with Pylon, you'll first need to set up Bun (opens in a new tab) and npm (opens in a new tab). You can install Node.js and npm by following the instructions on the official Node.js website (opens in a new tab).
Install the Pylon CLI globally:
npm install -g @getcronit/pylon-cli
Creating a new project
To create a new Pylon project, run the following command:
pylon new my-pylon-project
This will create a new directory called my-pylon-project
with a basic Pylon project structure.
Project structure
Pylon projects are structured as follows:
my-pylon-project/
├── .pylon/
├── src/
│ ├── index.ts
├── package.json
├── tsconfig.json
.pylon/
: Contains the production build of your project.src/
: Contains the source code of your project.src/index.ts
: The entry point of your Pylon service.package.json
: The npm package configuration file.tsconfig.json
: The TypeScript configuration file.
Basic example
Here's an example of a basic Pylon service:
import { defineService } from "@getcronit/pylon";
export default defineService({
Query: {
sum: (a: number, b: number) => a + b,
},
Mutation: {
divide: (a: number, b: number) => a / b,
},
});
Info
Note that there is no need to define a GraphQL schema in Pylon. The framework automatically generates the schema based on the defined queries and mutations.
Starting the development server
Navigate to the project directory and start the development server:
cd my-pylon-project
bun run develop
Your Pylon server should now be running at http://localhost:3000
.
Building for production
To build your Pylon project for production, run the following command:
bun run build
This will generate a production-ready build of your project in the .pylon
directory.
Deploying to production
To deploy your Pylon project to production, you can use the included Dockerfile or any other deployment method of your choice.
- Docker deployment (recommended):
Pylon comes with a pre-configured Dockerfile that you can use to deploy your project. To build and run your project using Docker, run the following commands:
docker build -t my-pylon-project .
docker run -p 3000:3000 my-pylon-project
Your Pylon server should now be running in a Docker container at http://localhost:3000
.
- Manual deployment:
You can deploy your Pylon project to any hosting provider that supports Bun applications. Simply copy the contents of the .pylon
directory to your server and run the following command:
pylon-server
The Pylon server supports HTTPS and custom ports, so you can configure it to fit your deployment needs.
Run pylon-server --help
for more information on available options.
Warning
Make sure that that you have installed the pylon-server
package before
running the command. This can be done globally or locally in your project
directory: npm install -g @getcronit/pylon-server
Built-in GraphQL Playground
Pylon comes with a built-in GraphQL Playground that you can use to interact with your service.
To access the Playground, navigate to http://localhost:3000/graphql
in your browser.
The Playground provides a graphical interface for testing queries and mutations, as well as documentation for your service.
Built-in GraphQL Viewer
Pylon also comes with a built-in GraphQL Viewer that you can use to view and navigate your service's schema.
To access the Viewer, navigate to http://localhost:3000/viewer
in your browser.
The viewer provides a visual representation of your service's schema, including types, queries, and mutations.
Info
The Pylon viewer is real-time and automatically updates as you make changes to your service. When using the viewer while developing your service, you can see the changes reflected immediately and understand how they affect your schema.
Basic usage
Pylon can be used to build a wide range of applications, from simple APIs to complex web services. Here are some basic examples to get you started:
Query example
The following example fetches a list of starships from the Star Wars API using the fetch
function:
import { defineService } from "@getcronit/pylon";
interface Starship {
name: string;
model: string;
manufacturer: string;
}
export default defineService({
Query: {
starships: async () => {
const response = await fetch("https://swapi.dev/api/starships/");
const data = await response.json();
return data.results as Starship[];
},
},
});
Now you can query the starships
field in your GraphQL client to fetch a list of starships from the Star Wars API.
Although the fetch returns a much larger object, Pylon will only return the data specified in the Starship
interface.
Mutation example
The following example defines a simple mutation that adds two numbers together:
import { defineService } from "@getcronit/pylon";
export default defineService({
Mutation: {
add: (a: number, b: number) => a + b,
},
});
This example defines a simple add
mutation that takes two numbers as arguments and returns their sum.
The types of the arguments and return value are inferred from the TypeScript types.
Custom starwars API
The following example defines a custom Star Wars API using a class to manage a list of characters:
import { defineService } from "@getcronit/pylon";
class StarWarsStore {
private characters = [
{ id: 1, name: "Luke Skywalker", height: 172 },
{ id: 2, name: "Darth Vader", height: 202 },
];
constructor() {
// Bind methods in order to access `this`
this.getCharacter = this.getCharacter.bind(this);
this.getCharacters = this.getCharacters.bind(this);
this.addCharacter = this.addCharacter.bind(this);
this.deleteCharacter = this.deleteCharacter.bind(this);
}
getCharacter(id: number) {
return this.characters.find((character) => character.id === id);
}
getCharacters() {
return this.characters;
}
addCharacter(name: string, height: number) {
const id = this.characters.length + 1;
this.characters.push({ id, name, height });
return { id, name, height };
}
deleteCharacter(id: number) {
const character = this.getCharacter(id);
if (character) {
this.characters = this.characters.filter((c) => c.id !== id);
return character;
}
return null;
}
}
const store = new StarWarsStore();
export default defineService({
Query: {
character: store.getCharacter,
characters: store.getCharacters,
},
Mutation: {
addCharacter: store.addCharacter,
deleteCharacter: store.deleteCharacter,
},
});
This example defines a custom Star Wars API with a StarWarsStore
class that manages a list of characters.
The API provides queries to fetch a single character or a list of characters, as well as mutations to add and delete characters.
Highly complex types
Pylon supports almost all TypeScript types, including complex types like interfaces and custom classes. You can define custom classes and interfaces to manage your data and use them in your service code.
To show the power of Pylon, the next example returns the Math
class of the JavaScript standard library:
import { defineService } from "@getcronit/pylon";
export default defineService({
Mutation: {
math: Math,
},
});
Now the math
mutation will return the Math
class of the JavaScript standard library, which contains a variety of mathematical constants and functions.
By using the Math
class in this way, you can remote control the Math
class from your GraphQL client.
Custom error handling
Error handling in Pylon is straightforward and can be customized to fit your needs. You can throw an error anywhere in your service code, and Pylon will automatically catch it and return the error message to the client. By default, Pylon masks all errors to prevent leaking sensitive information to the client.
When using the ServiceError
class, you can define custom error messages and status codes:
import { defineService, ServiceError } from "@getcronit/pylon";
export default defineService({
Query: {
throwError: () => {
throw new ServiceError("This is a custom error message", {
statusCode: 400,
code: "CUSTOM_ERROR",
});
},
},
});
You can also use the details
property to provide additional information about the error:
import { defineService, ServiceError } from "@getcronit/pylon";
export default defineService({
Query: {
throwError: () => {
throw new ServiceError("This is a custom error message", {
statusCode: 400,
code: "CUSTOM_ERROR",
details: {
foo: "bar",
},
});
},
},
});
Getting Help
Documentation
For comprehensive documentation on Pylon, including API references and advanced guides, visit the Pylon documentation website.
Community Support
Join the Pylon community for support and discussion:
- Pylon GitHub Issues (opens in a new tab): Report bugs and feature requests.
Professional Support
For professional support and consulting services, please contact [email protected].