Skip to content

Instantly share code, notes, and snippets.

View stemmlerjs's full-sized avatar

Khalil Stemmler stemmlerjs

View GitHub Profile
@stemmlerjs
stemmlerjs / schema.graphql
Created November 8, 2019 15:48
Federation Example #2 - Review schema demonstrating usage of the base User from Accounts Service
"""
A review is any feedback about products
"""
type Review @key (fields: "id") {
id: ID!
"The plain text version of the review"
body: String
"The user who authored the review. @provides directive refers back to "
author: User @provides (fields: "username")
@stemmlerjs
stemmlerjs / schema.graphql
Created November 8, 2019 15:47
Federation Example #1 - Account schema demonstrating the base User from the Accounts service
"""
The Base User from `Account` service
"""
"The key directive is the field we're going to use to identify the user"
type User @key(fields: "id") {
"A globally unique id for the user"
id: ID!
"The user's full name as provided"
name: String
@stemmlerjs
stemmlerjs / account-schema.graphql
Created November 8, 2019 14:29
GraphQL Federation Example
"""
The Base User from `Account` service
"""
"The key directive is the field we're going to use to identify the user"
type User @key(fields: "id") {
"A globally unique id for the user"
id: ID!
"The user's full name as provided"
name: String
@stemmlerjs
stemmlerjs / aggregate-or-domain-services.ts
Last active March 24, 2021 21:50
An example of the trade offs using either aggregates or using domain services to encapsulate business logic. Based on code from https://khalilstemmler.com/articles/typescript-domain-driven-design/ddd-vs-crud-design/
/*
* By designing the Customer as an Aggregate Root and including a reference all of the
* movies that it rented, we can place the validation logic for renting movies
* directly on the customer entity.
*
* Advantages: More declarative-reading code. The operation is a lot closer to the
* entity itself, which improves the discoverability and understanding what a customer
* can do.
*
* Disadvantages: Additional overhead. Having to pull the ids of rented movie everytime we
class CreateUserController extends BaseController {
private userRepo: IUserRepo;
constructor (userRepo: IUserRepo) {
this.userRepo = userRepo;
}
public execute (req: express.Request, res: express.Response): void {
try {
const { username, password, email } = req.body;
class CreateUserController extends BaseController {
public execute (req: express.Request, res: express.Response): void {
try {
const { username, password, email } = req.body;
const usernameOrError: Result<Username> = Username.create(username);
const passwordOrError: Result<Password> = Password.create(password);
const emailOrError: Result<Email> = Email.create(email);
const result = Result.combine([
usernameOrError, passwordOrError, emailOrError
// Abstract method from the CreateUserController
abstract execute (req: express.Request, res: express.Response): void;
class CreateUserController extends BaseController {
public execute (req: express.Request, res: express.Response): void {
try {
// ... Handle request by creating objects
} catch (err) {
return this.fail(res, err.toString())
}
}
}
@stemmlerjs
stemmlerjs / BaseController.ts
Last active September 5, 2023 19:00
Abstract Express.js controller for Node.js web apps
import * as express from 'express'
export abstract class BaseController {
abstract execute (req: express.Request, res: express.Response): void;
public static jsonResponse (res: express.Response, code: number, message: string) {
return res.status(code).json({ message })
}
public ok<T> (res: express.Response, dto?: T) {
import { CharmanderFactory } from 'pokemon/charmander/factory'
import { BulbasaurFactory } from 'pokemon/bulbasaur/factory'
import { PorygonFactory } from 'pokemon/porygon/factory'
enum PokemonType {
CHARMANDER = 'charmander',
BULBASAUR = 'bulbasaur',
PORYGON = 'porygon'
}