npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

my-fetcher

v1.1.3

Published

Buscador dinâmico para API Rest, tendo como base o swr e o axios, com ele você pode deixar mais fluido seu trabalho de salvar dados em loja e configurar requisições

Downloads

38

Readme

Atenção

Estou mudando o nome do pacote para dinamicfetch, todas as atualizaçõe serão voltadas para ele, vocês podem pesquisar no npm por esse nome. dinamicfetch

Instalação

    npm install --save my-fetcher

DEMO Obs: ver o readme.md desse demo no codesandbox

youtube

O que é o my-fetcher ?

Muitas vezes fazemos nossas chamadas de api na mão, usando o axios ou o fetch diretamente. Tendo em vista isso, é meio cansativo configurar como os dados devem ser manipulados.

É aí que entra o my-fetcher, um buscador dinâmico para API Rest, tendo como base o swr e o axios, com ele você pode deixar mais fluido seu trabalho de salvar resultados em store e configurar requisições. Além disso, ele trás uma proposta de padronização de dados, na qual essa documentação recomenda dicas de como usar uma store e protocolos https, dicas estas que vou passar logo a diante.

Que metodologia ele trás?

Por enquanto, não vou falar tanto do my-fetcher, primeiro irei explicar como eu uso lojas em minhas aplicações e como uso os protocolos https, assim esse pacote no qual publiquei irá fazer mais sentido.

Bem, para a store irei usar o mobx, não se preocupe, ele é simples de entender, é usado para estado global. Aqui vai um exemplo bem simples de store com mobx.

    import { observable, action} from 'mobx';

    let store = observable({
        users:[]
    });

    const update = action((key, value) => {
        store[key] = value;
    });

    export {update};
    export default store;

Certo, nos exemplos iremos trabalhar com o users, um model de usuários.

Vou começar falando sobre os protocolos https. Eu costumo usa-los dessa maneira:

  • Método GET: esse método eu uso apenas para retornar os dados da minha API. Por exemplo, quero trazer todos os usuários do banco de dados.
  • Método POST: esse método eu uso para inserir dados na minha API. Por exemplo, quero inserir um novo usuário no banco de dados.
  • Método PUT: esse método eu uso para atualizar dados na minha API. Por exemplo, quero mudar alguma informação de um usuário, como telefone ou endereço.
  • Método DELETE: esse método eu uso para remove dados na minha API. Por exemplo, quero apagar um usuário do banco de dados.

Certo, esses são os 4 métodos que eu uso, existem outros, mas por enquanto a função utilitária de tratamento de dados do my-fetcher só trabalhará com esses 4, que é o suficiente. Obs: não quero dizer que o my-fetcher não faça requisições com outros métodos, falo aqui de uma função utilitária, logo mais falarei sobre ela.

Vamos falar sobre a loja (eu costumo padronizar assim, isso vai ser importante para a manipulação de dados na store):

  • Chaves no plural: Por exemplo "users", perceber-se que está no plural, então na minha store eu quero dizer que ele é um array, no exemplo a cima defini inicialmente users: []
  • Chaves no singular: Pode ser qualquer valor. Por exemplo "user" posso inicialmente colocar assim user: {id:1, name:'Rodrigo'}

Vamos começar a falar o porquê de tudo isso.

Não vou entrar a fundo no my-fetcher agora, mas vou mostrar aqui um casos básico de uso para você entender a metodologia. Os valores retornados na promisse não são "exatamente" o que o my-fetcher irá trazer

O my-fetcher trabalha com esses parâmetros:

    import {fetch} from 'my-fetcher';
    fetch('<method>', '<url>', '<model>', '<body>', '<key>', '<config>'); //promisse

    /*
        <method>: Poder ser por exemplo, GET, POST, PUT, DELETE
        <url>: A rota da api
        <model>: O modelo na loja na qual o my-fetcher irá tratar os dados.
        <body>: Corpo da requisição, dados para enviar para o servidor
        <key>: Usado quando o método é PUT, isso indica qual atributo devo pegar como referência para atualizar os dados.
        <config>: Irei falar sobre isso mais na frente.
    */

Para você entender como faço buscas em minhas APIs, iremos seguir esses passos: buscar usuários, inserir um novo usuário, editar um usuáro, excluir um usuário.

Primeiro eu envio um GET para buscar todos os usuários:

    fetch('get', 'https://host/api/users', 'users').then(data=>{
        /*
            data retorna:
            {
                data:[
                    {id:1, name:'Rodrigo'},
                    {id:2, name:'Platão'},
                    {id:3, name:'Aristóteles'},
                    {id:4, name:'Sócrates'}
                ],
                dispatch:{
                    users:[
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                        {id:3, name:'Aristóteles'},
                        {id:4, name:'Sócrates'}
                    ]
                }
            }
        */
    });

Ok, próximo passo, agora eu quero inserir um novo usuário, irei enviar uma requisição com esse body: {name:'Paula'} e eu também retorno esse novo usuário inserido: res.status(200).send({id:5, name:'Paula'}). Observe que uso o método POST quando quero inserir algo no banco.

    fetch('post', 'https://host/api/users', 'users', {name:'Paula'}).then(data=>{
        /*
            data retorna:
            {
                data:{id:5, name:'Paula'},
                dispatch:{
                    users:[
                        {id:5, name:'Paula'}, //novo usuário aqui
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                        {id:3, name:'Aristóteles'},
                        {id:4, name:'Sócrates'}
                    ]
                }
            }
        */
    });
    fetch('put', 'https://host/api/users', 'users', {userId:3, name:'Fabrício'}, 'id').then(data=>{
        /*
            data retorna:
            {
                data:{id:3, name:'Fabrício'},
                dispatch:{
                    users:[
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                        {id:3, name:'Fabrício'}, //nome do usuário editado
                        {id:4, name:'Sócrates'},
                        {id:5, name:'Paula'},
                    ]
                }
            }
        */
    });

Observe que o dispatch pega o modelo users da loja e já trás os dados com o usuário 3 atualizado.

Ok, próximo passo, agora eu quero deletar o usuário de id 4, Sócrates. Observe que uso o método DELETE quando quero deletar algo no banco.

    fetch('delete', 'https://host/api/users/4', 'users', null, 'id').then(data=>{
        /*
            data retorna:
            {
                data:{id:4},
                dispatch:{
                    users:[
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                        {id:3, name:'Fabrício'},
                        {id:5, name:'Paula'},
                    ]
                }
            }
        */
    });

Quando for o método DELETE sempre retorno um json {[key]:[value]} indicando a chave que vou usar como referência, passado no 5° parâmetro do fetch. Isso irá pegar o modelo users da loja, vai procurar o usuário de id 4 e irá remove-lo.

Recapitularizando

Aqui em cima lhe mostrei como padronizo meus dados de api para GET, POST, PUT e DELETE e o que o fetch faz com os dados para cada método. Agora daqui para baixo irei explicar como usar o my-fetcher.

Como usar?

Primeiramente irei mostrar a função genérica, não vamos focar no swr ainda.

    import {fetch} from 'my-fetcher';
    fetch('<method>', '<url>', '<model>', '<body>', '<key>', '<config>'); //promisse

    /*
        <method>: Poder ser por exemplo, GET, POST, PUT, DELETE
        <url>: A rota da api
        <model>: O modelo na loja, cujo o my-fetcher irá tratar os dados.
        <body>: Corpo da requisição, dados para enviar para o servidor
        <key>: Usado quando o método é PUT, isso indica qual atributo devo pegar como referência para atualizar os dados na loja.
        <config>: {
            swr:{-configurações do swr-},
            axios:{-configurações do axios-},
            params: {
                -Parâmetros que quero passar na url-
            }
        }
    */

Usando com o método create

    import {create} from 'my-fetcher';

    let config = create({
        swr:{/*-configurações do swr-*/},
        axios:{/*-configurações do axios-*/},
        store:Store, // Aqui eu passo a loja - opcional,
        token:/*-pode ser o token passado quando um usuário estiver logado, isso irá ajudar o swr a diferenciar o cachê, já que ele trabalha com cachê de requiições-*/,
        onStart(data){
            // Chamado antes de uma determinada requisição ser executada.
            /*
                data retorna:
                {
                    method, // O método que uma determinada requisição está usando
                    url, // A url que uma determinada requisição está usando
                    model, // O modelo que está sendo passado como parâmetro para uma determinada requisição
                    body, // O corpo de uma determinada requisição
                    key, // O key que está sendo passado como parâmetro para uma determinada requisição
                    config // As configurações que estão sendo passadas como parâmetro para uma determinada requisição
                }
            */
        },
        onSuccess(data){
            // Chamado quando uma requisição termina de ser executada.
            /*
                data retorna:
                {
                    ...todos os dados que é retornado no axios por padrão,
                    model, 
                    key, 
                    dispatch // esse atributo retorna os dados que devem ser inseridos na loja, atualizados, ou deletados conforme a resposta da api.
                }
            */
        },
        onError(err){
            //--retorna um erro da requisição, se ouver
        },
        $onSuccess(data){
            /*
                retorna o mesmo que onSuccess, a diferença é que esse evento é disparado quando usamos o my-fetcher como hook tendo como base o swr.
            */
        },
        params: {
            /*-Parâmetros global que quero passar na url-*/
        }
    })

    config.fetch('<method>', '<url>', '<model>', '<body>', '<key>', '<config>');

    //---todos esses parâmetros irão ser detalhados mais tarde.

Explorando as utilidades

    import {create, fetch, $fetch, get, post, put, remove, $get, $post, $put, $remove} from 'my-fetcher'; //onde tem $ é quando quero usar o swr.
    //todas as funções a cima retorna uma promisse.

    //Essas aqui servem para facilitar sua vida, elas só aceitam parâmetros necessários, ao contrário de fetch, $fetch.
    get('<target>', '<model>', '<config>');
    post('<target>', '<model>', '<body>', '<config>');
    put('<target>', '<model>', '<body>', '<key>', '<config>');
    remove('<target>', '<model>', '<key>', '<config>'); // conidere como DELETE

    //----$get, $post, $put, $remove é usado da mesma maneira que as funções listadas a cima.

Trabalhando com mais de um model

    fetch('put', 'https://host/api/usersinfos', 'get-users, put-address', {name:'Rua tal - número tal'}, ', fk_id_users').then(data=>{
        /*
            data retorna:
            {
                data:{
                    users: [
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                    ],
                    address: {id:2, fk_id_users:1, name:'Rua tal - número tal'}
                },
                dispatch:{
                    users:[
                        {id:1, name:'Rodrigo'},
                        {id:2, name:'Platão'},
                    ],
                    address:[
                        {id:1, fk_id_users:2, name:'Rua tal - número tal'}, //--endereço editado
                        {id:2, fk_id_users:1, name:'Rua tal 2 - número tal 2'}
                    ]
                }
            }
        */
    });

Observe o get-users, put-address aqui eu digo que quero que o model users se comporte como um get, ou seja, o dispatch somente irá inserir os dados que foi retornado no data.users. Além disso, digo que o model address deve se comportar como um put, ou seja, no data.address retorno o endereço atualizado, conforme os valores que passei no body, e o dispatch o rescreve em dispatch.address.

No terceiro parâmetro, temos ,fk_id_users o primeiro valor (antes da virgula) não passo nada, ele se refere a get-users, mas get-users não precisa de uma key, pois ele é get, já o segundo valor (depois da vírgula) é o fk_id_users, é a chave que passo para dizer ao put-address com qual referência ele deve trabalhar para pesquiar na loja o endereço e substituir pelo novo.

Detalhe importante, aqui em cima na última linha eu disse "substituir pelo novo", o my-fetcher não interfere na sua loja, apenas usa os dados da store para fazer o tratamento necessário e lhe entregar a resposta em dispatch, você pode alterar os valores de sua loja em onSuccess.

Trabalhando com swr

    let {data, error, isValidating, mutate} = $get('/users', 'users', {axios:{}, swr:{/*-configurações do swr-*/}});

    //--para quem conhece o SWR, saberá que ele é um hook e que funciona trazendo esses dados mostrados a cima, a diferença é que aqui estou integrando com o my-fetcher

Bom, por enquanto é isso, a forma que você vai usa-lo vai depender de sua criatividade, recomendo sempre usar a função create para configurar de forma global sua aplicação, lá você pode configurar mensagens de alerta como mostra no demo, salvar os dados na store e o que você desejar fazer.