Created
March 24, 2021 13:00
-
-
Save max10rogerio/6afe3cddd1ed94f18f0424d628f1d5e0 to your computer and use it in GitHub Desktop.
Exemplo mostrando em como padronizar a resposta de uma api para camelCase e separar as resposabilidades
This file contains hidden or 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
interface Api { | |
post: <R = any, P = any>(params: P) => Promise<R> | |
} | |
/* | |
A api espera user_login, user_password | |
E response user_name, user_age, user_status | |
*/ | |
type ApiResponse = { | |
user_name: string | |
user_age: number | |
user_status: boolean | |
user_last_name: string | |
} | |
type ApiParams = { | |
user_login: string | |
user_password: string | |
} | |
type AuthLoginHttpResponse = { | |
name: string | |
lastName: string | |
age: number | |
status: boolean | |
} | |
type AuthLoginHttpParams = { | |
username: string | |
password: string | |
} | |
// aqui só reaproveitei o tipo | |
// mas se fosse necessário mudar meu service já tem um tipo independente | |
type AuthLoginServiceParams = AuthLoginHttpParams | |
type AuthLoginServiceResponse = { | |
fullName: string | |
age: number | |
} | |
// o repository fica encarregado de formatar o objeto para o que o serviço externo esperar | |
// nesse caso é o snake_case | |
// ele também fica encarregado de padronizar a resposta para camelCase | |
export class AuthLoginHttp { | |
constructor(private readonly api: Api) {} | |
public async login(params: AuthLoginHttpParams): Promise<AuthLoginHttpResponse> { | |
const payload = this.makeParams(params) | |
const response = await this.api.post<ApiResponse, ApiParams>(payload) | |
return this.makeResponse(response) | |
} | |
private makeParams(params: AuthLoginHttpParams): ApiParams { | |
return { | |
user_login: params.username, | |
user_password: params.password, | |
} | |
} | |
private makeResponse(payload: ApiResponse): AuthLoginHttpResponse { | |
return { | |
name: payload.user_name, | |
lastName: payload.user_last_name, | |
age: payload.user_age, | |
status: payload.user_status, | |
} | |
} | |
} | |
// então o service já recebe os valores padronizado em camelCase | |
export class AuthLoginService { | |
constructor(private readonly authLoginHttp: AuthLoginHttp) {} | |
// no caso aqui no service ficaria a regra de negócio | |
public async login(params: AuthLoginServiceParams): Promise<AuthLoginServiceResponse> { | |
const result = await this.authLoginHttp.login(params) | |
// ai nesse caso o service fica com uma logica para validar o status do usuário | |
if (result.status) { | |
throw new Error('Invalid User') | |
} | |
// retorna o tipo que de objeto q o service espera | |
return this.makeResponse(result) | |
} | |
// mesmo q parece simples montar o nome completo, e que até faria sentido montar o nome completo já no repository | |
// esse caso pode ser considerado uma regra de negócio tbm | |
// mas tudo varia de caso para caso | |
private makeResponse(payload: AuthLoginHttpResponse): AuthLoginServiceResponse { | |
return { | |
fullName: `${payload.name} ${payload.lastName}`, | |
age: payload.age, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment