-
-
Save kibolho/bceadfe823de7fb440bef41c77428081 to your computer and use it in GitHub Desktop.
SOLID - Dependency Inversion Principle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// infra/HttpClient.ts | |
import axios from "axios"; | |
export default { | |
createUser: async (user: User) => { | |
return axios.post(/* ... */); | |
}, | |
getUserByEmail: async (email: string) => { | |
return axios.get(/* ... */); | |
}, | |
}; | |
// domain/SignupService.ts | |
import HttpClient from "infra/HttpClient"; // ❌ the domain depends on a concretion from the infra | |
export async function signup(email: string, password: string) { | |
const existingUser = await HttpClient.getUserByEmail(email); | |
if (existingUser) { | |
throw new Error("Email already used"); | |
} | |
return HttpClient.createUser({ email, password }); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// domain/ApiClient.ts | |
export interface ApiClient { | |
createUser: (user: User) => Promise<void>; | |
getUserByEmail: (email: string) => Promise<User>; | |
// ... | |
} | |
// infra/HttpClient.ts | |
import axios from "axios"; | |
import ApiClient from "domain/ApiClient"; | |
export function HttpClient(): ApiClient { | |
return { | |
createUser: async (user: User) => { | |
return axios.post(/* ... */); | |
}, | |
getUserByEmail: async (email: string) => { | |
return axios.get(/* ... */); | |
}, | |
}; | |
} | |
// domain/SignupService.ts | |
import ApiClient from "domain/ApiClient"; // ✅ the domain depends on an abstraction of the infra | |
export function SignupService(client: ApiClient) { | |
return async (email: string, password: string) => { | |
const existingUser = await client.getUserByEmail(email); | |
if (existingUser) { | |
throw new Error("Email already used"); | |
} | |
return client.createUser({ email, password }); | |
}; | |
} | |
// index.ts -> With the power of dependency inversion, our SignupService can now use any ApiClient. Let's inject our HttpClient for now: | |
import SignupService from "domain/signup"; | |
import HttpClient from "infra/HttpClient"; | |
const signup = SignupService(HttpClient()); | |
signup("bob@bob.com", "pwd123"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment