Skip to content

Commit 7fc7121

Browse files
working api insert into database
1 parent c855604 commit 7fc7121

7 files changed

Lines changed: 56 additions & 37 deletions

File tree

apps/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "main.js",
66
"scripts": {
77
"typecheck": "tsc",
8-
"dev": "tsx src/main.ts"
8+
"dev": "tsx watch src/main.ts"
99
},
1010
"keywords": [],
1111
"author": "",

apps/server/src/database.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PgClient } from "@effect/sql-pg";
2+
import { Config } from "effect";
3+
4+
export const DatabaseLive = PgClient.layerConfig({
5+
password: Config.redacted("POSTGRES_PW"),
6+
username: Config.succeed("postgres"),
7+
database: Config.succeed("postgres"),
8+
host: Config.succeed("localhost"),
9+
port: Config.succeed(5435),
10+
});

apps/server/src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { ServerApi } from "@local/api";
1313
import { Effect, Layer } from "effect";
1414
import { createServer } from "node:http";
15-
import { DatabaseLive } from "./migration";
15+
import { MigratorLive } from "./migrator";
1616
import { RestApiLive } from "./rest";
1717

1818
const EnvProviderLayer = Layer.unwrapEffect(
@@ -23,7 +23,7 @@ const EnvProviderLayer = Layer.unwrapEffect(
2323
);
2424

2525
const MainApiLive = HttpApiBuilder.api(ServerApi).pipe(
26-
Layer.provide([DatabaseLive, RestApiLive]),
26+
Layer.provide([MigratorLive, RestApiLive]),
2727
Layer.provide(EnvProviderLayer)
2828
);
2929

apps/server/src/migration.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

apps/server/src/migrator.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { NodeContext } from "@effect/platform-node";
2+
import { PgMigrator } from "@effect/sql-pg";
3+
import { Layer } from "effect";
4+
import { fileURLToPath } from "node:url";
5+
import { DatabaseLive } from "./database";
6+
7+
export const MigratorLive = PgMigrator.layer({
8+
// Where to put the `_schema.sql` file
9+
schemaDirectory: "src/migrations",
10+
loader: PgMigrator.fromFileSystem(
11+
fileURLToPath(new URL("migrations", import.meta.url))
12+
),
13+
}).pipe(Layer.provide([DatabaseLive, NodeContext.layer]));

apps/server/src/rest.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
11
import { HttpApiBuilder } from "@effect/platform";
2-
import { Example, ServerApi } from "@local/api";
3-
import { Effect } from "effect";
2+
import { SqlClient, SqlResolver } from "@effect/sql";
3+
import { ServerApi, User } from "@local/api";
4+
import { Effect, Layer, Schema } from "effect";
5+
import { DatabaseLive } from "./database";
46

57
export const RestApiLive = HttpApiBuilder.group(ServerApi, "rest", (handlers) =>
6-
handlers.handle("example", () =>
8+
handlers.handle("create-user", ({ payload }) =>
79
Effect.gen(function* () {
8-
return new Example({ id: crypto.randomUUID(), name: "example" });
9-
})
10+
const sql = yield* SqlClient.SqlClient;
11+
12+
const InsertPerson = yield* SqlResolver.ordered("InsertPerson", {
13+
Request: User.pipe(Schema.omit("id", "created_at")),
14+
Result: User,
15+
execute: (requests) =>
16+
sql`
17+
INSERT INTO "user"
18+
${sql.insert(requests)}
19+
RETURNING *
20+
`,
21+
});
22+
23+
return yield* InsertPerson.execute({ name: payload.name });
24+
}).pipe(
25+
Effect.tapError(Effect.logError),
26+
Effect.mapError((error) => error.message)
27+
)
1028
)
11-
);
29+
).pipe(Layer.provide(DatabaseLive));

packages/api/src/main.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { HttpApi, HttpApiEndpoint, HttpApiGroup } from "@effect/platform";
22
import { Schema } from "effect";
33

4-
export class Example extends Schema.Class<Example>("Example")({
5-
id: Schema.UUID,
4+
export class User extends Schema.Class<User>("User")({
5+
id: Schema.Number,
66
name: Schema.String,
7+
created_at: Schema.DateFromSelf,
78
}) {}
89

910
class RestGroup extends HttpApiGroup.make("rest").add(
10-
HttpApiEndpoint.get("example")`/example`
11+
HttpApiEndpoint.post("create-user")`/user/create`
12+
.setPayload(Schema.Struct({ name: Schema.String }))
1113
.addError(Schema.String)
12-
.addSuccess(Example)
14+
.addSuccess(User)
1315
) {}
1416

1517
export class ServerApi extends HttpApi.make("server-api").add(RestGroup) {}

0 commit comments

Comments
 (0)