MCPcopy Create free account
hub / github.com/Effect-TS/effect / Users

Class Users

ai-docs/src/51_http-server/fixtures/server/Users.ts:32–183  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

30})
31
32export class Users extends Context.Service<Users, {
33 list(search: string | undefined): Effect.Effect<Array<User>, UsersError>
34 getById(id: UserId): Effect.Effect<User, UsersError>
35 create(input: typeof User.jsonCreate.Type): Effect.Effect<User, UsersError>
36 update(id: UserId, input: typeof User.jsonUpdate.Type): Effect.Effect<User, UsersError>
37}>()("acme/Users") {
38 // The SQL implementation only requires a `SqlClient`, so entrypoints and
39 // tests decide how the database is provided.
40 static readonly layerNoDeps = Layer.effect(
41 Users,
42 Effect.gen(function*() {
43 const sql = yield* SqlClient.SqlClient
44
45 // CRUD goes through a repository derived from the `User` model. Each
46 // operation uses the matching model variant to encode its input and
47 // decodes rows with the full model schema.
48 const repo = yield* SqlModel.makeRepository(User, {
49 tableName: "users",
50 spanPrefix: "Users",
51 idColumn: "id"
52 })
53
54 // Queries the repository does not cover are written with the `sql` tag
55 // and decoded with the model schema.
56 const listAll = SqlSchema.findAll({
57 Request: Schema.Void,
58 Result: User,
59 execute: () => sql`SELECT * FROM users ORDER BY createdAt`
60 })
61
62 const searchUsers = SqlSchema.findAll({
63 Request: Schema.String,
64 Result: User,
65 execute: (search) => {
66 const pattern = `%${search}%`
67 return sql`SELECT * FROM users WHERE name LIKE ${pattern} OR email LIKE ${pattern}`
68 }
69 })
70
71 const list = Effect.fn("Users.list")(function*(search: string | undefined) {
72 if (search === undefined || search.length === 0) {
73 return yield* Effect.orDie(listAll())
74 } else if (search.length < SearchQueryTooShort.minimumLength) {
75 return yield* new UsersError({
76 reason: new SearchQueryTooShort()
77 })
78 }
79 yield* Effect.annotateCurrentSpan({ search })
80 return yield* Effect.orDie(searchUsers(search))
81 })
82
83 const getById = Effect.fn("Users.getById")((id: UserId) =>
84 repo.findById(id).pipe(
85 Effect.catchTags({
86 NoSuchElementError: () => new UsersError({ reason: new UserNotFound() }),
87 // Database and encoding failures are unexpected, so treat them as
88 // defects to keep the service interface focused on domain errors.
89 SchemaError: Effect.die,

Callers

nothing calls this directly

Calls 8

filterMethod · 0.80
pipeMethod · 0.65
makeEffectMethod · 0.65
ofMethod · 0.65
setMethod · 0.65
getMethod · 0.65
updateMethod · 0.45
provideMethod · 0.45

Tested by

no test coverage detected