Skip to content

Latest commit

 

History

History
530 lines (421 loc) · 8.88 KB

slides.md

File metadata and controls

530 lines (421 loc) · 8.88 KB
theme title drawings transition mdc colorSchema aspectRatio themeConfig plantUmlServer layout
default
Arquitetura Front-end orientada a Dados
persist
slide-left
true
dark
16/9
primary
#5d8392
cover

Arquitetura Front-end orientada a Dados


Paulo Cândido @paulhenrique
{ 
  "name": "Paulo Cândido",
  "professional": [
    "Senior Frontend Develiper no CPQD",
    "Organizador do Front in Campinas",
    "Membro da Liga voluntária do MWPT"
  ],
  "technologies": [
    "React", "Vue", "Typescript", "3D Maps", "Progressive Web Apps" 
  ],
  "likes": [
    "Animes", "Séries", "The Office", "Musician"
  ]
}

hide: true

Agenda

  • A API nunca está pronta quando começamos o frontend;
  • Mock, o salvador da pátria;
  • Miragem, uma forma de resolver o problema;
  • Arquitetura voltada a mutação de dados;
    • Isolando serviços;
    • Isolando chamada de API;
    • Mock com types;

layout: cover

São dois caminhos

Ou API existe e precisamos construir uma interface para interagir com ela, ou (o que é mais comum) a API e Interface serão construídas ao mesmo tempo.

É sobre isso, e tá tudo bem!


layout: cover

Mock, o salvador da pátria

Vamos pensar em uma aplicação de consulta de usuários.


layout: intro

Usuário

  • Buscar usuários

  • Cadastrar usuários

  • Atualizar usuários

  • Excluir usuários


transition: slide-up level: 2

O comum

Criar um serviço que retorna os usuários


export const ENDPOINTS = {
  USER: "/api/users"
}

const UserService = {
  findAll: (): User[] => {
    const response = await fetch(ENDPOINTS.USER);
    const data = await response.json();
    return data;
  },
}

transition: slide-up level: 3

Criando um "mock"

Cria um JSON para o mock, o que é bastante interessante

{
  "users": [
    {
      "id": 1,
      "username": "anakin",
      "email": "anakin@example.com"
    },
    {
      "id": 2,
      "username": "padme",
      "email": "padme@example.com"
    },
     {
      "id": 2,
      "username": "kenobi ",
      "email": "kenobi  @example.com"
    }
  ]
}

transition: slide-up level: 3

Ainda no comum

Os devs colocam um retorno direto substituindo a chamada do serviço

import UsersJson from './mock/users.json';

const MOCK_ACTIVE = true; // define se o mock será aplicado ou não

export const ENDPOINTS = {
  USER: "/api/users"
}

const UserService = {
  findAll: (): User[] => {
    if(MOCK_ACTIVE) {
      return UsersJson.users;
    }
    const response = await fetch(ENDPOINTS.USER);
    const data = await response.json();
    return data;
  },
}

transition: slide-up level: 3 layout: intro

Como escalar isso?

Simples, não escala


layout: two-cols transition: slide-up

import UsersJson from './mock/users.json';

const MOCK_ACTIVE = true;

export const ENDPOINTS = {
  USER: "/api/users"
}

const UserService = {
  findAll: (): User[] => {
    if(MOCK_ACTIVE) {
      return UsersJson.users;
    }
    const response = await fetch(ENDPOINTS.USER);
    const data = await response.json();
    return data;
  },
}

antes

::right::

import ApiServices from 'services/ApiServices';
export const ENDPOINTS = {
  USER: "/api/users"
}

const UserService = {
  findAll: (): User[] => {
    return ApiServices.find(ENDPOINTS.USER);
  },
}

depois


Isolando os serviços de API

O nascimento do API Services

const ApiServices = {
  find: async (endpoint: string) => {
    const response = await fetch(endpoint);
    const data = await response.json();
    return data;
  },
  create: async <T>(endpoint: string, data: T) => {
    const response = await fetch(endpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    });
    const dataResponse = await response.json();
    return dataResponse;
  },
  delete: async <T>(endpoint: string, data: T) => {
    const response = await fetch(endpoint, {
      method: "DELETE",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    });
    const dataResponse = await response.json();
    return dataResponse;
  },
};

export default apiServices;

layout: intro

Onde colocar os mocks agora?

Uma dúvida cruel, por que não os isolar?


layout: intro

Uma miragem

O Mirage JS


transition: slide-up

Manipulação de Rotas


this.get("/users", { users: ["Anakin", "Padme", "Kenobi"] })

APIs em diferentes hosts


routes() {
  this.urlPrefix = 'http://localhost:3000';
...        

Manipulação de retorno com função


this.get("/users", (schema, request) => {
  return ["Anakin", "Padme", "Kenobi"]
})

Manipulando operações HTTP

this.get('/users', () => { ... });
this.post('/users', () => { ... });
this.patch('/users/:id', () => { ... });
this.put('/users/:id', () => { ... });
this.del('/users/:id', () => { ... });
this.options('/users', () => { ... });

Timing

this.get(
  "/users",
  () => {
    return ["Anakin", "Padme", "Kenobi"]
  },
  { timing: 4000 }
)

transition: slide-up layout: intro

Acessando a camada de dados


transition: slide-up

Retornando dados do Schema

this.get("/users", (schema) => {
  return schema.users.all()
})

Buscando com parâmetros

this.get("/users/:id", (schema, request) => {
  let id = request.params.id

  return schema.users.find(id)
})

Requisições com body

this.post("/movies", (schema, request) => {
  let attrs = JSON.parse(request.requestBody)

  return schema.movies.create({ attrs })
})

layout: intro transition: slide-up

Precisamos disso tudo apenas para um mock?

A resposta é que: Depende


Simples

import UsersJson from './mock/users.json';
import { createServer } from "miragejs"

createServer({
  routes() {
    this.namespace = 'api';
    this.get("/users", UsersJson.users);
  }
})
Nada muda no nosso serviço de usuários
import ApiServices from 'services/ApiServices';
export const ENDPOINTS = {
  USER: "/api/users"
}

const UserService = {
  findAll: (): User[] => {
    return ApiServices.get(ENDPOINTS.USER);
  },
}
Nem nos serviços da API
const apiServices = {
  find: async (endpoint: string) => {
    const response = await fetch(endpoint);
    const data = await response.json();
    return data;
  },
  ...
};

layout: intro

Isso escala?

Sim, e de forma bem mais Simples


layout: intro

Por enquanto é só!

Muito obrigado!

Paulo Cândido @paulhenrique