Bucket
Source:
src/Railway/Bucket.ts
A Railway.Bucket is S3-compatible object storage in a Project. Each
environment gets its own isolated instance and credentials. Bind
PutObject / GetObject (and the other S3 object ops) in
Service init — Alchemy injects the endpoint and credentials.
Railway has no labels. Ownership is stamped into the display name via
createPhysicalName. name updates in place. Changing project,
environment, or region replaces the Bucket.
Create a Bucket
Section titled “Create a Bucket”Pass a Project. Alchemy generates a unique name and deploys to the
project’s primary environment in sjc.
const site = yield* Railway.Project("Site");const data = yield* Railway.Bucket("Data", { project: site });A stable name
Section titled “A stable name”Pass name when you need a stable display name. The S3 API name is
this plus a short hash (s3BucketName).
const data = yield* Railway.Bucket("Data", { project: site, name: "uploads",});Region
Section titled “Region”Omit region to use sjc. Changing it replaces the Bucket.
const data = yield* Railway.Bucket("Data", { project: site, region: "iad",});Environment
Section titled “Environment”Defaults to the Project’s primary environment. Pass a
Railway.Environment (or { environmentId }) to target another one.
const staging = yield* Railway.Environment("Staging", { project: site });const data = yield* Railway.Bucket("StagingData", { project: site, environment: staging,});Put and get objects
Section titled “Put and get objects”Railway buckets speak the S3 API. Bind PutObject /
GetObject in Service init.
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
export default class Api extends Railway.Service<Api>()( "Api", { project: Site, main: import.meta.url }, Effect.gen(function* () { const putObject = yield* Railway.PutObject(Data); const getObject = yield* Railway.GetObject(Data);
return { fetch: Effect.gen(function* () { yield* putObject({ Key: "hello.txt", Body: "hello", ContentType: "text/plain", }); const obj = yield* getObject({ Key: "hello.txt" }); return HttpServerResponse.json({ ok: obj.ETag !== undefined }); }), }; }).pipe(Effect.provide([Railway.PutObjectHttp, Railway.GetObjectHttp])),) {}Module-scope declarations
Section titled “Module-scope declarations”Declare the Project once. Pass it into every child. Resource-valued props accept the resource or an Effect producing it.
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");export const Data = Railway.Bucket("Data", { project: Site });