Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an examples directory, with a first example of a simple express server #8

Merged
merged 2 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/express-server/ConfigSchema.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
address: String
port: Int16
32 changes: 32 additions & 0 deletions examples/express-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# PklTypescript Example: Express server

This is an example of a simple TypeScript program that uses Pkl for configuration.

## Hand-written code

A summary of each of the files in this directory, and what they do:

- `index.ts`: contains the source code of the express app
- `ConfigSchema.pkl`: contains the schema of the configuration (just the properties and their types, but not any values)
- `config.dev.pkl`: amends `ConfigSchema.pkl`, adding the config values that would be used in local development
- `config.prod.pkl`: amends `ConfigSchema.pkl` but with values to be used in production

## Generated code

There is also another directory, `generated`, that contains `.pkl.ts` files that were generated by `pkl-gen-typescript` based on the given schema.

The `package.json` has a script, titled `gen-config` (but the script name doesn't matter), that executes the following:

```bash
pkl-gen-typescript ./ConfigSchema.pkl -o ./generated
```

This uses the `pkl-gen-typescript` CLI, passing in `ConfigSchema.pkl` as the Pkl module to be evaluated, and outputting the generated TypeScript files to the `./generated` directory.

## Running the app

1. Run `npm install` in this directory to install dependencies (including a local link to the `pkl-typescript` project at the root of this repo)
1. Run `npm run gen-config` to make sure the generated `.pkl.ts` files in the `./generated` directory are up-to-date
1. Run `npm run start` to start the local dev server

Then, in another terminal, run `curl localhost:3003` to see a response from your Pkl-configured Express server.
4 changes: 4 additions & 0 deletions examples/express-server/config.dev.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
amends "ConfigSchema.pkl"

address = "localhost"
port = 3003
4 changes: 4 additions & 0 deletions examples/express-server/config.prod.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
amends "ConfigSchema.pkl"

address = "example.com"
port = 443
24 changes: 24 additions & 0 deletions examples/express-server/generated/config_schema.pkl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This file was generated by `pkl-typescript` from Pkl module `ConfigSchema`.
// DO NOT EDIT.
import * as pklTypescript from "@pkl-community/pkl-typescript"

// Ref: Module root.
export interface ConfigSchema {
address: string

port: number
}

// LoadFromPath loads the pkl module at the given path and evaluates it into a ConfigSchema
export const loadFromPath = async (path: string): Promise<ConfigSchema> => {
const evaluator = await pklTypescript.newEvaluator(pklTypescript.PreconfiguredOptions);
try {
const result = await load(evaluator, pklTypescript.FileSource(path));
return result
} finally {
evaluator.close()
}
};

export const load = (evaluator: pklTypescript.Evaluator, source: pklTypescript.ModuleSource): Promise<ConfigSchema> =>
evaluator.evaluateModule(source) as Promise<ConfigSchema>;
21 changes: 21 additions & 0 deletions examples/express-server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import express from "express";
import { loadFromPath } from "./generated/config_schema.pkl";

const app = express();

app.get("/", (_, res) => {
res.send("Hello from a pkl-configured app!");
});

// The config file to evaluate can be dynamically chosen based on the value of NODE_ENV
const configFile = `config.${process.env.NODE_ENV ?? "dev"}.pkl`;

// Use pkl-typescript to load and evaluate the selected Pkl file
loadFromPath(configFile).then((config) => {
console.log("Loaded config values from Pkl:", JSON.stringify(config));

// `config` is a typed object, of the schema given in ConfigSchema.pkl
app.listen(config.port, config.address, () => {
console.log("Server started");
});
});
Loading
Loading