Run it once
Post the script to the server, get the result back. Requests take no parameters.
request Greeting {
const name = "Ada"
return "Hello ${name}!"
}{ "returnValue": "Hello Ada!" }RequestScript is a small, strictly typed scripting language that you send to a server to run. Instead of calling a fixed set of endpoints, put the logic in the request body and get exactly the result you need.
pnpm add requestscriptrequest Forecast {
const weather: com.example.Weather
const t = weather.temperature(city: "Oslo")
if (t.error != null) {
return t.error.message
}
return { city: "Oslo", celsius: t.value }
}{
"returnValue": { "city": "Oslo", "celsius": 4.5 }
}Every variable has a type that never changes, and values are never silently converted. if (1) is an error, not a guess.
Integers never wrap and decimal arithmetic is exact, so 0.1 + 0.2 == 0.3 is true. Built for prices and quantities.
No loops and no user-defined functions. A script runs top to bottom and returns a value, so it is easy to review.
A failing resource call hands the script an error it can inspect, instead of failing the whole request.
two kinds of scripts
Every script is either a request, run once and discarded, or a contract: named, versioned, saved on the server and invoked later with JSON parameters.
Post the script to the server, get the result back. Requests take no parameters.
request Greeting {
const name = "Ada"
return "Hello ${name}!"
}{ "returnValue": "Hello Ada!" }Contracts are immutable per version. Publish @2 next to @1 and move clients over when they are ready.
contract shop.orders.LineTotal@2(item: object, taxRate: decimal(1, 4)) {
const subtotal: decimal = item.price * item.quantity
return { total: subtotal + subtotal * taxRate }
}{ "parameters": { "item": { "price": 9.99, "quantity": 2 }, "taxRate": 0.0825 } }embed it
The reference implementation is the requestscript package. Its root export is the language itself (lexer, parser, exact decimals and interpreter) with no server or database, so it runs in Node, at the edge and in the browser. The playground below runs on it.
import { createResourceResolver, interpret } from 'requestscript';
const result = await interpret(source, {
resourceResolver: createResourceResolver([weather]),
parameters: { city: 'Oslo' },
});
console.log(result.returnValue);import { createResourceResolver } from 'requestscript';
import { startServer } from 'requestscript/server';
// Connects to Postgres, runs migrations and listens.
await startServer({
port: 3000,
resourceResolver: createResourceResolver([weather]),
middleware: [authMiddleware],
});playground
Scripts run locally on the real interpreter, and the result is shaped exactly like the server's HTTP response. Pick an example or write your own.
request HelloWorldPOST /runPress Run to execute the script in your browser.com.example.Weather.temperature(city: string): decimalshop.Inventory.stock(sku: string): int32The language is open source and young, which makes now the best time to influence it. Report issues, fix bugs, improve the docs, or bring it to a new host language.