Consumo do Supabase

JavaScript HTTP Clients

Existem várias formas de fazer requisições assíncronas em JavaScript. Veja as principais opções:

Fetch API

Fetch API é a API nativa do navegador para requisições HTTP.

Vantagens:

Desvantagens:

Axios

Axios é uma biblioteca HTTP popular que funciona em navegador e Node.js.

Vantagens:

Desvantagens:

Supabase Client

@supabase/supabase-js é a biblioteca oficial do Supabase para JavaScript.

Vantagens:

Desvantagens:

Demonstração

Fetch API

fetch(resource)
fetch(resource, options)
fetch(resource)
fetch(resource, options)

Exemplo

/codes/w3c/fetch-api/via-cep/index.js
async function getCep(cep) {
  const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
  const res = await fetch(resource);
 
  return await res.json();
}
 
const cep = '58015430';
 
// then
const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
fetch(resource)
  .then((res) => res.json())
  .then((data) => console.log(data));
 
// async await
const data = await getCep(cep);
 
console.log(data);
 
/codes/w3c/fetch-api/via-cep/index.js
async function getCep(cep) {
  const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
  const res = await fetch(resource);
 
  return await res.json();
}
 
const cep = '58015430';
 
// then
const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
fetch(resource)
  .then((res) => res.json())
  .then((data) => console.log(data));
 
// async await
const data = await getCep(cep);
 
console.log(data);
 

Cross-Origin Resource Sharing (CORS)

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Credentials
  • Access-Control-Max-Age

O Fetch API é uma alternativa ao XMLHttpRequest

Axios Library: axios

$ npm install axios
$ npm install axios
/codes/package/axios/via-cep/index.js
import axios from 'axios';
 
const cep = '58015430';
 
const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
axios.get(resource).then((response) => console.log(response.data));
 
/codes/package/axios/via-cep/index.js
import axios from 'axios';
 
const cep = '58015430';
 
const resource = `https://viacep.com.br/ws/${cep}/json/`;
 
axios.get(resource).then((response) => console.log(response.data));
 

Supabase Client: @supabase/supabase-js

$ npm install @supabase/supabase-js
$ npm install @supabase/supabase-js

Exemplo:

import { createClient } from '@supabase/supabase-js';
 
const supabase = createClient(
  'https://xyz.supabase.co',
  'public-anon-key'
);
 
const { data, error } = await supabase
  .from('investments')
  .select();
 
console.log(data);
import { createClient } from '@supabase/supabase-js';
 
const supabase = createClient(
  'https://xyz.supabase.co',
  'public-anon-key'
);
 
const { data, error } = await supabase
  .from('investments')
  .select();
 
console.log(data);

Invest-app (CRUD)

Veja como implementar as operações CRUD (Create, Read, Update, Delete) com cada biblioteca:

Código Fonte Fetch

Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
/codes/w3c/fetch-api/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/w3c/fetch-api/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/w3c/fetch-api/invest-app/js/services/storage.js
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL;
const API_TOKEN = import.meta.env.VITE_APP_SUPABASE_KEY;
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };
/codes/w3c/fetch-api/invest-app/js/services/storage.js
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL;
const API_TOKEN = import.meta.env.VITE_APP_SUPABASE_KEY;
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };

Código Fonte Axios

Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       ├── api.js
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       ├── api.js
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
/codes/package/axios/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/package/axios/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/package/axios/invest-app/js/services/storage.js
import API from '/services/api.js';
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };
/codes/package/axios/invest-app/js/services/storage.js
import API from '/services/api.js';
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };

Axios Config:

/codes/package/axios/invest-app/js/services/api.js
import axios from 'axios';
 
const API_KEY = import.meta.env.VITE_APP_SUPABASE_KEY;
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL + '/rest/v1';
 
export default axios.create({
  baseURL: API_URL,
  headers: {
    common: {
      apikey: API_KEY,
      Authorization: `Bearer ${API_KEY}`,
    },
    post: {
      Prefer: 'return=representation',
    },
    patch: {
      Prefer: 'return=representation',
    },
  },
});
 
/codes/package/axios/invest-app/js/services/api.js
import axios from 'axios';
 
const API_KEY = import.meta.env.VITE_APP_SUPABASE_KEY;
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL + '/rest/v1';
 
export default axios.create({
  baseURL: API_URL,
  headers: {
    common: {
      apikey: API_KEY,
      Authorization: `Bearer ${API_KEY}`,
    },
    post: {
      Prefer: 'return=representation',
    },
    patch: {
      Prefer: 'return=representation',
    },
  },
});
 

Código Fonte Supabase Client

Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
Arquivos
invest-app
├── css
│   └── style.css
├── index.html
├── js
│   ├── components
│   │   ├── InvestmentCard.js
│   │   ├── InvestmentForm.js
│   │   └── Modal.js
│   ├── lib
│   │   ├── dom.js
│   │   ├── format.js
│   │   └── investments.js
│   ├── main.js
│   └── services
│       └── storage.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   └── vite.svg
└── tailwind.config.js
/codes/package/supabase-client/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/package/supabase-client/invest-app/.env.example
VITE_APP_SUPABASE_KEY=
VITE_APP_SUPABASE_URL=
/codes/package/supabase-client/invest-app/js/services/storage.js
import { createClient } from '@supabase/supabase-js';
 
const API_KEY = import.meta.env.VITE_APP_SUPABASE_KEY;
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL;
 
const supabase = createClient(API_URL, API_KEY);
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };
/codes/package/supabase-client/invest-app/js/services/storage.js
import { createClient } from '@supabase/supabase-js';
 
const API_KEY = import.meta.env.VITE_APP_SUPABASE_KEY;
const API_URL = import.meta.env.VITE_APP_SUPABASE_URL;
 
const supabase = createClient(API_URL, API_KEY);
 
async function create(resource, data) {}
async function read(resource, id) {}
async function update(resource, id, data) {}
async function remove(resource, id) {}
 
export default { create, read, update, remove };

Create a investment

/codes/w3c/fetch-api/invest-api-doc/create.js
async function create(resource, data) {
  resource = `${API_URL}/${resource}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
      Prefer: 'return=representation',
      'Content-Type': 'application/json',
    },
    method: 'POST',
    body: JSON.stringify(data),
  };
 
  const res = await fetch(resource, options);
 
  const createdData = await res.json();
 
  return createdData?.[0];
}
 
/codes/w3c/fetch-api/invest-api-doc/create.js
async function create(resource, data) {
  resource = `${API_URL}/${resource}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
      Prefer: 'return=representation',
      'Content-Type': 'application/json',
    },
    method: 'POST',
    body: JSON.stringify(data),
  };
 
  const res = await fetch(resource, options);
 
  const createdData = await res.json();
 
  return createdData?.[0];
}
 
/codes/package/axios/invest-api-doc/create.js
async function create(resource, data) {
  const { data: createdData } = await API.post(resource, data);
 
  return createdData?.[0];
}
 
/codes/package/axios/invest-api-doc/create.js
async function create(resource, data) {
  const { data: createdData } = await API.post(resource, data);
 
  return createdData?.[0];
}
 
/codes/package/supabase-client/invest-api-doc/create.js
async function create(resource, data) {
  const { data: createdData, error } = await supabase
    .from(resource)
    .insert(data)
    .select('*');
 
  if (error) {
    throw error;
  }
 
  return createdData?.[0];
}
 
/codes/package/supabase-client/invest-api-doc/create.js
async function create(resource, data) {
  const { data: createdData, error } = await supabase
    .from(resource)
    .insert(data)
    .select('*');
 
  if (error) {
    throw error;
  }
 
  return createdData?.[0];
}
 
import Storage from './services/storage.js';
 
const investment = {
  name: "Tesouro Selic 2029",
  value: 10000,
  origin: "Tesouro Direto",
  category: "Pós",
  interest: "100% Selic",
  created_at: "2021-09-10T00:00:00-03:00",
};
 
Storage.create('investments', investment);
import Storage from './services/storage.js';
 
const investment = {
  name: "Tesouro Selic 2029",
  value: 10000,
  origin: "Tesouro Direto",
  category: "Pós",
  interest: "100% Selic",
  created_at: "2021-09-10T00:00:00-03:00",
};
 
Storage.create('investments', investment);

Read investments

/codes/w3c/fetch-api/invest-api-doc/read.js
async function read(resource, id) {
  resource = id
    ? `${API_URL}/${resource}?id=eq.${id}`
    : `${API_URL}/${resource}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
    },
    method: 'GET',
  };
 
  const res = await fetch(resource, options);
 
  return await res.json();
}
 
/codes/w3c/fetch-api/invest-api-doc/read.js
async function read(resource, id) {
  resource = id
    ? `${API_URL}/${resource}?id=eq.${id}`
    : `${API_URL}/${resource}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
    },
    method: 'GET',
  };
 
  const res = await fetch(resource, options);
 
  return await res.json();
}
 
/codes/package/axios/invest-api-doc/read.js
async function read(resource, id) {
  if (id) {
    resource = `${resource}?id=eq.${id}`;
  }
 
  const { data } = await API.get(resource);
 
  return data;
}
 
/codes/package/axios/invest-api-doc/read.js
async function read(resource, id) {
  if (id) {
    resource = `${resource}?id=eq.${id}`;
  }
 
  const { data } = await API.get(resource);
 
  return data;
}
 
/codes/package/supabase-client/invest-api-doc/read.js
async function read(resource, id) {
  const { data, error } = id
    ? await supabase.from(resource).select('*').eq('id', id)
    : await supabase.from(resource).select('*');
 
  if (error) {
    throw error;
  }
 
  return data;
}
 
/codes/package/supabase-client/invest-api-doc/read.js
async function read(resource, id) {
  const { data, error } = id
    ? await supabase.from(resource).select('*').eq('id', id)
    : await supabase.from(resource).select('*');
 
  if (error) {
    throw error;
  }
 
  return data;
}
 
import Storage from './services/storage.js';
 
Storage.read('investments');
Storage.read('investments', 1);
import Storage from './services/storage.js';
 
Storage.read('investments');
Storage.read('investments', 1);

Update a investment

/codes/w3c/fetch-api/invest-api-doc/update.js
async function update(resource, id, data) {
  resource = `${API_URL}/${resource}?id=eq.${id}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
      Prefer: 'return=representation',
      'Content-Type': 'application/json',
    },
    method: 'PATCH',
    body: JSON.stringify(data),
  };
 
  const res = await fetch(resource, options);
 
  const updatedData = await res.json();
 
  return updatedData?.[0];
}
 
/codes/w3c/fetch-api/invest-api-doc/update.js
async function update(resource, id, data) {
  resource = `${API_URL}/${resource}?id=eq.${id}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
      Prefer: 'return=representation',
      'Content-Type': 'application/json',
    },
    method: 'PATCH',
    body: JSON.stringify(data),
  };
 
  const res = await fetch(resource, options);
 
  const updatedData = await res.json();
 
  return updatedData?.[0];
}
 
/codes/package/axios/invest-api-doc/update.js
async function update(resource, id, data) {
  resource = `${resource}?id=eq.${id}`;
 
  const { data: updatedData } = await API.patch(resource, data);
 
  return updatedData?.[0];
}
 
/codes/package/axios/invest-api-doc/update.js
async function update(resource, id, data) {
  resource = `${resource}?id=eq.${id}`;
 
  const { data: updatedData } = await API.patch(resource, data);
 
  return updatedData?.[0];
}
 
/codes/package/supabase-client/invest-api-doc/update.js
async function update(resource, id, data) {
  const { data: updatedData, error } = await supabase
    .from(resource)
    .update(data)
    .eq('id', id)
    .select('*');
 
  if (error) {
    throw error;
  }
 
  return updatedData?.[0];
}
 
/codes/package/supabase-client/invest-api-doc/update.js
async function update(resource, id, data) {
  const { data: updatedData, error } = await supabase
    .from(resource)
    .update(data)
    .eq('id', id)
    .select('*');
 
  if (error) {
    throw error;
  }
 
  return updatedData?.[0];
}
 
import Storage from './services/storage.js';
 
Storage.update('investments', 1, { value: 15000 });
import Storage from './services/storage.js';
 
Storage.update('investments', 1, { value: 15000 });

Delete a investment

/codes/w3c/fetch-api/invest-api-doc/delete.js
async function remove(resource, id) {
  resource = `${API_URL}/${resource}?id=eq.${id}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
    },
    method: 'DELETE',
  };
 
  const res = await fetch(resource, options);
 
  return res.ok;
}
 
/codes/w3c/fetch-api/invest-api-doc/delete.js
async function remove(resource, id) {
  resource = `${API_URL}/${resource}?id=eq.${id}`;
 
  const options = {
    headers: {
      apikey: API_TOKEN,
      Authorization: `Bearer ${API_TOKEN}`,
    },
    method: 'DELETE',
  };
 
  const res = await fetch(resource, options);
 
  return res.ok;
}
 
/codes/package/axios/invest-api-doc/delete.js
async function remove(resource, id) {
  resource = `${resource}?id=eq.${id}`;
 
  const { error } = await API.delete(resource);
 
  if (error) {
    throw error;
  } else {
    return true;
  }
}
 
/codes/package/axios/invest-api-doc/delete.js
async function remove(resource, id) {
  resource = `${resource}?id=eq.${id}`;
 
  const { error } = await API.delete(resource);
 
  if (error) {
    throw error;
  } else {
    return true;
  }
}
 
/codes/package/supabase-client/invest-api-doc/delete.js
async function remove(resource, id) {
  const { error } = await supabase.from(resource).delete().eq('id', id);
 
  if (error) {
    throw error;
  } else {
    return true;
  }
}
 
/codes/package/supabase-client/invest-api-doc/delete.js
async function remove(resource, id) {
  const { error } = await supabase.from(resource).delete().eq('id', id);
 
  if (error) {
    throw error;
  } else {
    return true;
  }
}
 
import Storage from './services/storage.js';
 
Storage.remove('investments', 1);
import Storage from './services/storage.js';
 
Storage.remove('investments', 1);

Editar esta página