Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Teaser] Type-Safe Lightweight DDD with Effect ...

[Teaser] Type-Safe Lightweight DDD with Effect Schema

Going to be presenting at JSConf JP 2024.
Full version: https://decks.yasaichi.com/20241123/type-safe-lightweight-ddd-with-effect-schema

Yuichi Goto

November 17, 2024
Tweet

More Decks by Yuichi Goto

Other Decks in Programming

Transcript

  1. import { Cause, Effect } from 'effect'; Effect.succeed({ id: 1n,

    name: 'yasaichi' }) satisfies Effect.Effect<User>; const getUserRequest = ( userId: bigint ): Effect.Effect<any, Cause.UnknownException> => Effect.tryPromise(() => fetch(`${API_ORIGIN}/users/${userId}`).then((res) => res.json()) ); const parseUser = (data: unknown): Effect.Effect<User, Error> => Effect.try({ try: () => User.parse(data), catch: () => new Error('Failed to parse user'), });
  2. // Unlike Promises, you must explicitly run effects using these

    methods. await Effect.runPromise(getUserRequest(1n)); // => { id: "1", name: "yasaichi", ... } // You do not use `runSync` usually because there is no way to know in advance // if an effect will execute synchronously or asynchronously. Effect.runSync(parseUser({ id: '1', name: '' })); // throws (FiberFailure) Error: Failed to parse user
  3. // Using Pipe & Functor/Monad const getUserByIdUsingPipe = ( userId:

    bigint ): Effect.Effect<User, Error | Cause.UnknownException> => getUserRequest(userId).pipe(Effect.andThen(parseUser)); // Using Generator & yield* const getUserByIdUsingGenerator = ( userId: bigint ): Effect.Effect<User, Error | Cause.UnknownException> => Effect.gen(function* () { const res = yield* getUserRequest(userId); return yield* parseUser(res); });