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.

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); });