Skip to content

Instantly share code, notes, and snippets.

@max10rogerio
Created March 24, 2021 13:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save max10rogerio/6afe3cddd1ed94f18f0424d628f1d5e0 to your computer and use it in GitHub Desktop.
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
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