Mudanças entre as edições de "Javascript: CRUD Rest"

De Aulas
 
(3 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
 +
 +
 +
 +
 
Afluentes: [[Desenvolvimento Front-end I]], [[Usabilidade, desenvolvimento web, mobile e jogos]].
 
Afluentes: [[Desenvolvimento Front-end I]], [[Usabilidade, desenvolvimento web, mobile e jogos]].
  
Linha 5: Linha 9:
 
Para que nosso CRUD possa ser funcional, precisamos de um serviço web com as operações de CRUD (CREATE, READ, UPDATE e DELETE). Para o nosso exemplo aqui, usarei um serviço web desenvolvido em linguagem de programação GO:
 
Para que nosso CRUD possa ser funcional, precisamos de um serviço web com as operações de CRUD (CREATE, READ, UPDATE e DELETE). Para o nosso exemplo aqui, usarei um serviço web desenvolvido em linguagem de programação GO:
  
* [[Go: RESTful - um exemplo completo com persistência]]
+
* [[Go: RESTful - exemplo com persistência, gorm, e segurança]]
  
 
Caso você queira reimplementar o serviço em Node.js ou outra linguagem/framework, basta entender o manual de acesso ao serviço web:
 
Caso você queira reimplementar o serviço em Node.js ou outra linguagem/framework, basta entender o manual de acesso ao serviço web:
Linha 14: Linha 18:
 
O arquivo <code>index.html</code> contem a formatação básica da nossa aplicação
 
O arquivo <code>index.html</code> contem a formatação básica da nossa aplicação
  
<syntaxhighlight lang=html>
+
<syntaxhighlight lang="html">
 
<!doctype html>
 
<!doctype html>
 
<html lang="pt-br">
 
<html lang="pt-br">
Linha 20: Linha 24:
 
<head>
 
<head>
 
     <meta charset="utf-8">
 
     <meta charset="utf-8">
     <title>Funcionários</title>
+
     <title>Usuários</title>
     <script src="api.js"></script>
+
     <script src="script.js"></script>
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
+
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
     <link rel="stylesheet" href="index.css">
+
     <link rel="stylesheet" href="style.css">
 
</head>
 
</head>
  
Linha 30: Linha 34:
 
     <p>
 
     <p>
 
         <label for="id">ID:</label>
 
         <label for="id">ID:</label>
         <input type="number" id="id">
+
         <input type="text" id="id">
 
     </p>
 
     </p>
 
     <p>
 
     <p>
Linha 43: Linha 47:
 
         <button class="button" onclick="gravar();">Gravar</button>
 
         <button class="button" onclick="gravar();">Gravar</button>
 
         <button class="button" onclick="limpar();">Limpar</button>
 
         <button class="button" onclick="limpar();">Limpar</button>
 +
        <button class="button" onclick="carregarDados();limpar();">Recarregar</button>
 
     </p>
 
     </p>
 
     <table>
 
     <table>
Linha 50: Linha 55:
 
                 <th>Nome</th>
 
                 <th>Nome</th>
 
                 <th>E-mail</th>
 
                 <th>E-mail</th>
                 <th></th>
+
                 <th>Ações</th>
 
             </tr>
 
             </tr>
 
         </thead>
 
         </thead>
         <tbody id="tbody"></tbody>
+
         <tbody id="tbody">
 +
        </tbody>
 
     </table>
 
     </table>
 
</body>
 
</body>
Linha 64: Linha 70:
 
O arquivo <code>api.js</code> contem os códigos em javascript para o acesso às operações GET, POST, PUT e DELETE do nosso serviço web.
 
O arquivo <code>api.js</code> contem os códigos em javascript para o acesso às operações GET, POST, PUT e DELETE do nosso serviço web.
  
<syntaxhighlight lang=javascript>
+
<syntaxhighlight lang="javascript">
 
+
/**
// link do nosso serviço web. Estamos utilizando o localhost na porta 8080
+
* Vamos precisar de um link para acessar nosso serviço. No caso, estamos
// e o o serviço, especificamente, é o user.
+
* utilizando o localhost na porta 8080 e nosso endpoint é /users
 +
* Veja que nesse exemplo estamos acessando um serviço que requer autenticação
 +
* usando X-KEY e X-API-KEY, então já configuramos o cabeçalho com esses
 +
* parâmetros.
 +
*/
  
var url = "http://localhost:8080/users";
+
//var url = "http://localhost:8080/users";
 +
var url = 'https://api.arisa.com.br/users';
 +
const headers = {
 +
    'Content-Type': 'application/json; charset=utf-8',  // Mensagens JSON
 +
    "X-User": "fulano",                                // Usuário
 +
    'X-API-KEY': "12345",                              // API-KEY
 +
};
  
 
/**
 
/**
Linha 75: Linha 91:
 
  */
 
  */
 
async function carregarDados() {
 
async function carregarDados() {
     let tbody = document.getElementById('tbody');
+
     let tbody = document.getElementById('tbody'); // instanciamos o corpo da tabela
     tbody.innerHTML = "";
+
     tbody.innerHTML = "";                         // e limpamos seu conteúdo
 
     try {
 
     try {
         const response = await fetch(url, {                         // Usamos a operação GET
+
         const response = await fetch(url, {       // Fazemos a chamada ao serviço
             method: "GET",                                         // sem parâmetros que retorna
+
             method: 'GET',                         // usando a operação GET
             dataType: "json",
+
             headers: headers,                     // e passamos os cabeçalhos
 
         });
 
         });
         const result = await response.json();                       // uma lista de objetos JSON
+
         const result = await response.json();     // retorna uma lista de objetos JSON
         result.forEach(row => {                                     // para cada objeto da lista
+
         result.forEach(row => {                   // para cada objeto da lista
             let tr = document.createElement("tr");                 // cria uma linha da tabela
+
             let tr = document.createElement("tr"); // cria uma linha da tabela
             tr.innerHTML =
+
             tr.innerHTML = (`
                 `<td>${row.id}</td>
+
                 <td>${row.id}</td>
 +
                <td onClick="selecionar(${row.id});">${row.name}</td>
 +
                <td>${row.email}</td>
 
                 <td>
 
                 <td>
                     <a href="#" onclick="selecionar(${row.id});">
+
                     <button
                        ${row.name}</a>
+
                        type="button"
 +
                        onClick="excluir(${row.id});"
 +
                    >Excluir</button>
 
                 </td>
 
                 </td>
                <td>${row.email}</td>
+
            `);
                <td>
+
             tbody.appendChild(tr);                 // Criada a linha, adicionamos
                    <a href="#" onclick="excluir(${row.id});">
+
         });                                       // no corpo da tabela
                        <i class="fa fa-trash-alt"></i></a>
 
                </td>`;
 
             tbody.appendChild(tr);                                 // Criada a linha, adicionamos
 
         });                                                         // no corpo da tabela
 
 
     } catch (error) {
 
     } catch (error) {
 
         alert("Error: " + error);
 
         alert("Error: " + error);
Linha 105: Linha 121:
 
/**
 
/**
 
  * Retorna apenas um objeto JSON com o id selected_id
 
  * Retorna apenas um objeto JSON com o id selected_id
* @param {*} selected_id
 
 
  */
 
  */
 
async function selecionar(selected_id) {
 
async function selecionar(selected_id) {
 
     let id = document.getElementById('id');
 
     let id = document.getElementById('id');
     id.disabled = true;                                             // Desabilitamos o ID porque
+
     id.disabled = true;                           // Desabilitamos o campo ID porque
     let name = document.getElementById('name');                     // vamos alterar pelo ID
+
     let name = document.getElementById('name');   // vamos alterar pelo ID
 
     let email = document.getElementById('email');
 
     let email = document.getElementById('email');
 
     try {
 
     try {
         const response = await fetch(`${url}/${selected_id}`, {     // Buscamos pela url com parâmetro id
+
        // Buscamos pela url com parâmetro id
 +
         const response = await fetch(`${url}/${selected_id}`, {
 
             method: "GET",
 
             method: "GET",
             dataType: "json"
+
             headers: headers,
         })
+
         });
         const user = await response.json();                         // Retorna um objeto e carregamos as
+
         const user = await response.json();         // Retorna um objeto e carregamos as
         id.value = user.id;                                         // informações retornadas nos campos texto
+
         id.value = user.id;                         // informações retornadas nos campos texto
 
         name.value = user.name;
 
         name.value = user.name;
 
         email.value = user.email;
 
         email.value = user.email;
Linha 126: Linha 142:
 
}
 
}
  
/**
+
async function excluir(id) {
* Exclui um registro pelo ID passado como parâmetro em selected_id
 
* @param {*} selected_id
 
*/
 
async function excluir(selected_id) {
 
 
     try {
 
     try {
         const response = await fetch(`${url}/${selected_id}`, {     // Consumimos o serviço com o parâmetro id
+
        // Usamos o serviço chamando pelo ID
             method: "DELETE",                                       // usando a operação DELETE
+
         const response = await fetch(`${url}/${id}`, { // Excluimos pelo ID
             dataType: "json",
+
             method: "DELETE",                           // chamamos a operação DELETE
        }).then(result => {                                        // Se deu tudo ok
+
             headers: headers,
            limpar();                                              // limpa os campos
 
            carregarDados();                                        // e recarrega a tabela
 
 
         });
 
         });
 +
        const result = await response.json();
 +
        limpar();
 +
        carregarDados();
 
     } catch (error) {
 
     } catch (error) {
 
         alert("Error: " + error);
 
         alert("Error: " + error);
Linha 152: Linha 165:
 
     let email = document.getElementById('email');
 
     let email = document.getElementById('email');
 
     let i_id = 0;
 
     let i_id = 0;
     if (isNaN(i_id = parseInt(id.value))) {                         // O id precisa ser um número inteiro
+
     if (isNaN(i_id = parseInt(id.value))) {         // O id precisa ser um número inteiro
 
         alert("O id precisa ser um inteiro.");
 
         alert("O id precisa ser um inteiro.");
 
         return;
 
         return;
 
     }
 
     }
     var data = {                                                   // Criamos nosso objeto JSON Para o envio
+
     var data = JSON.stringify({                     // Criamos nosso objeto JSON Para o envio
 
         id: i_id,
 
         id: i_id,
 
         name: name.value,
 
         name: name.value,
 
         email: email.value,
 
         email: email.value,
     };
+
     });
     let method = "POST";                                            // Se o campo ID estiver desabilitado, é porque
+
     // Se o campo ID estiver desabilitado, é porque estávamos alterando,
     if (id.disabled) method = "PUT";                                // estavamos alterando, então usa PUT, senão POST
+
     // então usa PUT, senão POST, pois é um novo registro.
     try {                                                           // porque é um novo registro
+
    let method = id.disabled ? 'PUT' : 'POST';
 +
     try {
 
         const response = await fetch(url, {
 
         const response = await fetch(url, {
 
             method: method,
 
             method: method,
             dataType: "json",
+
             headers: headers,
            contentType: "application/json; charset=utf-8",
+
             body: data,
             body: JSON.stringify(data),
+
         }).then(result => {                         // Se deu tudo ok
         }).then(result => {                                         // Se deu tudo ok
+
             limpar();                               // limpa os campos e habilita o id
             limpar();                                               // limpa os campos e habilita o id
+
             carregarDados();                       // e recarrega os dados da tabela
             carregarDados();                                       // e recarrega os dados da tabela
 
 
         });
 
         });
 
     } catch (error) {
 
     } catch (error) {
Linha 179: Linha 192:
  
 
/**
 
/**
  * Limpa os campos e habilita o campo ID que poderia estar desabilitado
+
  * Limpa os campos e habilita o campo ID que poderia
 +
* estar desabilitado.
 
  */
 
  */
 
function limpar() {
 
function limpar() {
Linha 189: Linha 203:
  
 
}
 
}
 +
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Edição atual tal como às 20h37min de 4 de novembro de 2024



Afluentes: Desenvolvimento Front-end I, Usabilidade, desenvolvimento web, mobile e jogos.

Serviço web

Para que nosso CRUD possa ser funcional, precisamos de um serviço web com as operações de CRUD (CREATE, READ, UPDATE e DELETE). Para o nosso exemplo aqui, usarei um serviço web desenvolvido em linguagem de programação GO:

Caso você queira reimplementar o serviço em Node.js ou outra linguagem/framework, basta entender o manual de acesso ao serviço web:

index.html

O arquivo index.html contem a formatação básica da nossa aplicação

<!doctype html>
<html lang="pt-br">

<head>
    <meta charset="utf-8">
    <title>Usuários</title>
    <script src="script.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
    <link rel="stylesheet" href="style.css">
</head>

<body onload="carregarDados();">
    <h1>Usuários</h1>
    <p>
        <label for="id">ID:</label>
        <input type="text" id="id">
    </p>
    <p>
        <label for="name">Nome:</label>
        <input type="text" id="name">
    </p>
    <p>
        <label for="email">E-mail:</label>
        <input type="text" id="email">
    </p>
    <p class="btn-group">
        <button class="button" onclick="gravar();">Gravar</button>
        <button class="button" onclick="limpar();">Limpar</button>
        <button class="button" onclick="carregarDados();limpar();">Recarregar</button>
    </p>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Nome</th>
                <th>E-mail</th>
                <th>Ações</th>
            </tr>
        </thead>
        <tbody id="tbody">
        </tbody>
    </table>
</body>

</html>

api.js

O arquivo api.js contem os códigos em javascript para o acesso às operações GET, POST, PUT e DELETE do nosso serviço web.

/**
 * Vamos precisar de um link para acessar nosso serviço. No caso, estamos
 * utilizando o localhost na porta 8080 e nosso endpoint é /users
 * Veja que nesse exemplo estamos acessando um serviço que requer autenticação
 * usando X-KEY e X-API-KEY, então já configuramos o cabeçalho com esses
 * parâmetros.
 */

//var url = "http://localhost:8080/users";
var url = 'https://api.arisa.com.br/users';
const headers = {
    'Content-Type': 'application/json; charset=utf-8',  // Mensagens JSON
    "X-User": "fulano",                                 // Usuário
    'X-API-KEY': "12345",                               // API-KEY
};

/**
 * Função assíncrona para carregar os dados na tabela
 */
async function carregarDados() {
    let tbody = document.getElementById('tbody');  // instanciamos o corpo da tabela
    tbody.innerHTML = "";                          // e limpamos seu conteúdo
    try {
        const response = await fetch(url, {        // Fazemos a chamada ao serviço
            method: 'GET',                         // usando a operação GET
            headers: headers,                      // e passamos os cabeçalhos
        });
        const result = await response.json();      // retorna uma lista de objetos JSON
        result.forEach(row => {                    // para cada objeto da lista
            let tr = document.createElement("tr"); // cria uma linha da tabela
            tr.innerHTML = (`
                <td>${row.id}</td>
                <td onClick="selecionar(${row.id});">${row.name}</td>
                <td>${row.email}</td>
                <td>
                    <button
                        type="button"
                        onClick="excluir(${row.id});"
                    >Excluir</button>
                </td>
            `);
            tbody.appendChild(tr);                 // Criada a linha, adicionamos
        });                                        // no corpo da tabela
    } catch (error) {
        alert("Error: " + error);
    }
}

/**
 * Retorna apenas um objeto JSON com o id selected_id
 */
async function selecionar(selected_id) {
    let id = document.getElementById('id');
    id.disabled = true;                            // Desabilitamos o campo ID porque
    let name = document.getElementById('name');    // vamos alterar pelo ID
    let email = document.getElementById('email');
    try {
        // Buscamos pela url com parâmetro id
        const response = await fetch(`${url}/${selected_id}`, {
            method: "GET",
            headers: headers,
        });
        const user = await response.json();         // Retorna um objeto e carregamos as
        id.value = user.id;                         // informações retornadas nos campos texto
        name.value = user.name;
        email.value = user.email;
    } catch (error) {
        alert("Error: " + error);
    }
}

async function excluir(id) {
    try {
        // Usamos o serviço chamando pelo ID
        const response = await fetch(`${url}/${id}`, {  // Excluimos pelo ID
            method: "DELETE",                           // chamamos a operação DELETE
            headers: headers,
        });
        const result = await response.json();
        limpar();
        carregarDados();
    } catch (error) {
        alert("Error: " + error);
    }
}

/**
 * Gravamos um objeto com os dados carregados dos campos texto
 */
async function gravar() {
    let id = document.getElementById('id');
    let name = document.getElementById('name');
    let email = document.getElementById('email');
    let i_id = 0;
    if (isNaN(i_id = parseInt(id.value))) {         // O id precisa ser um número inteiro
        alert("O id precisa ser um inteiro.");
        return;
    }
    var data = JSON.stringify({                     // Criamos nosso objeto JSON Para o envio
        id: i_id,
        name: name.value,
        email: email.value,
    });
    // Se o campo ID estiver desabilitado, é porque estávamos alterando,
    // então usa PUT, senão POST, pois é um novo registro.
    let method = id.disabled ? 'PUT' : 'POST';
    try {
        const response = await fetch(url, {
            method: method,
            headers: headers,
            body: data,
        }).then(result => {                         // Se deu tudo ok
            limpar();                               // limpa os campos e habilita o id
            carregarDados();                        // e recarrega os dados da tabela
        });
    } catch (error) {
        alert("Error: " + error);
    }
}

/**
 * Limpa os campos e habilita o campo ID que poderia
 * estar desabilitado.
 */
function limpar() {
    let id = document.getElementById('id');
    id.value = "";
    id.disabled = false;
    document.getElementById('name').value = "";
    document.getElementById('email').value = "";

}

index.css

Estou usando um CSS para deixar a parte visual mais bonita, mas o uso é opcional.

table {
    width: 100%;
}

th {
    background-color: #04AA6D;
    color: white;
}

td {
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

input[type=number],
input[type=text],
select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input[type=submit] {
    width: 100%;
    background-color: #4CAF50;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type=submit]:hover {
    background-color: #45a049;
}

div {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

input[type=submit],
input[type=reset] {
    background-color: #04AA6D;
    border: none;
    color: white;
    padding: 16px 32px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
}

.btn-group .button {
    background-color: #04AA6D;
    /* Green */
    border: none;
    color: white;
    padding: 10px 16px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    cursor: pointer;
}

.btn-group .button:hover {
    background-color: #3e8e41;
}