{"id":26233651,"url":"https://github.com/andytango/redux-postgrest-demo","last_synced_at":"2025-04-22T12:11:09.949Z","repository":{"id":41706854,"uuid":"242794526","full_name":"andytango/redux-postgrest-demo","owner":"andytango","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-05T08:28:27.000Z","size":4927,"stargazers_count":4,"open_issues_count":21,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T15:01:41.547Z","etag":null,"topics":["docker","microservices","postgres","postgresql","postgrest","react","reactjs","redux","redux-postgrest","sql","websocketd","websockets"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andytango.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-24T17:08:06.000Z","updated_at":"2024-12-12T06:25:46.000Z","dependencies_parsed_at":"2023-02-03T20:31:46.243Z","dependency_job_id":null,"html_url":"https://github.com/andytango/redux-postgrest-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andytango%2Fredux-postgrest-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andytango%2Fredux-postgrest-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andytango%2Fredux-postgrest-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andytango%2Fredux-postgrest-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andytango","download_url":"https://codeload.github.com/andytango/redux-postgrest-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237832,"owners_count":21397401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","microservices","postgres","postgresql","postgrest","react","reactjs","redux","redux-postgrest","sql","websocketd","websockets"],"created_at":"2025-03-13T01:16:59.080Z","updated_at":"2025-04-22T12:11:09.917Z","avatar_url":"https://github.com/andytango.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# redux-postgrest demo\n\nThis is a usable demo that illustrates how we can use just `React`, `Postgres` and friends to build an entire CRUD application by way of TodoMVC, *without writing a  back-end.*\n\nSo no Rails, Django, Laravel, Spring, Koa, Play et cetera.\n\n## Key Features\n\n- Dispatching actions to call the Postgrest API\n- Using selectors to retrieve API responses from the provided redux-postgrest store\n- Using a simple websocket implementation along with pg_websocket to keep front end data in sync - try using two browser windows side by side\n- Using clientside base64 encoding to upload and persist images in a Postgres `BYTEA` column\n\n## How does it work?\n\nMainly down to these rather fabulous packages and their authors:\n- [PostgREST](https://github.com/PostgREST/postgrest)\n- [pg_listen](https://github.com/begriffs/pg_listen)\n- [Websocketd](https://github.com/joewalnes/websocketd/)\n\nThis demo just glues everything together and adds some convenience features to make development as *effortless as possible*.\n\n![data flows](https://raw.githubusercontent.com/andytango/redux-postgrest-demo/master/redux-postgrest.png \"data flows\")\n\nWe also use:\n- [redux-postgrest](https://github.com/andytango/redux-postgrest) to translate redux actions into HTTP requests and responses\n- A really simple [docker container](https://github.com/andytango/pg_websocket/) to plug `pg_listen` into `websocketd`.\n\n## How much code are we talking about, exactly?\n\n### Setup\n- [Backend Stack](https://github.com/andytango/redux-postgrest-demo/blob/master/docker-compose.yml)\n- [Database Schema](https://github.com/andytango/redux-postgrest-demo/blob/master/db/setup.sql)\n- [Websocket Client](https://github.com/andytango/redux-postgrest-demo/blob/master/src/ws.js)\n\n### Redux\n- [Store](https://github.com/andytango/redux-postgrest-demo/blob/master/src/store.js)\n```js\nimport { applyMiddleware, combineReducers, createStore } from \"redux\";\nimport { composeWithDevTools } from \"redux-devtools-extension\";\nimport { connectPgRest } from \"redux-postgrest\";\nimport connectPgWebsocket from \"./helpers/ws\";\n\nconst { reducer, middleware } = connectPgRest({\n  url: \"http://localhost:8000\"\n});\n\nconst store = createStore(\n  combineReducers({ api: reducer }),\n  composeWithDevTools(\n    connectPgWebsocket({ url: \"ws://localhost:8080\" }),\n    applyMiddleware(middleware)\n  )\n);\n\nexport default store;\n```\n\n### React Hooks \n- [Hooks](https://github.com/andytango/redux-postgrest-demo/blob/master/src/hooks/todos.js)\n\n### React Components\n- [Create Todo Form](https://github.com/andytango/redux-postgrest-demo/blob/master/src/components/TodoForm.js)\n- [Todo List](https://github.com/andytango/redux-postgrest-demo/blob/master/src/components/TodoList.js)\n- [Todo List Item](https://github.com/andytango/redux-postgrest-demo/blob/master/src/components/TodoListItem.js)\n- [Edit Todo Form](https://github.com/andytango/redux-postgrest-demo/blob/master/src/components/TodoEditForm.js)\n- [Delete Todo Button](https://github.com/andytango/redux-postgrest-demo/blob/master/src/components/TodoDeleteButton.js)\n\nThat's it!\n\n## How do I run it?\n\n*You will need to install [docker](https://docs.docker.com/install/) and [docker-compose](https://docs.docker.com/compose/install/).*\n\n1. Clone this repo:\n```sh\ngit clone git@github.com:andytango/redux-postgrest-demo.git\n```\n\n2. As per usual:\n\n```sh\nyarn install\n```\n3. Then:\n```sh\nyarn start\n```\n4. Then:\n```sh\nyarn run db:setup\n```\n5. Add/edit/delete some todos\n\n6. For fun, try running this while the app is open in your browser:\n```sh\nyarn run db:clean\n```\n\n## But why?\n\nOver the past decade, browsers and databases like Postgres have grown in their sophistication and capabilities to the extent that simple, stateful applications can be built without a back-end server. \n\nSo why build and maintain three subsystems when you can get away with two?\n\n### Doesn't this mean writing lots of SQL?\nYep.\n\n### And can it scale?\n[Absolutely](http://postgrest.org/en/v6.0/#in-production). \n\n*For a large number of concurrent users (above say 10,000 depending on hardware), you'll want something more efficient than websocketd for your websockets, as it relies on forking UNIX processes.*\n\n### And what about the things that Postgres can't do, like working with external APIs?\nFor that you can go straight to [microservices](https://martinfowler.com/articles/microservices.html).\n\nThis isn't as hard as it sounds. The cost of developing in this way has been reduced by serverless products from cloud vendors, like AWS Lambda and GCP Run. \n\nOutside of the cloud, there's docker and docker-compose which have relatively shallow learning curves.\n\nIn fact, if you take a look at this project's [docker-compose file](https://github.com/andytango/redux-postgrest-demo/blob/master/docker-compose.yml), you'll see that this backend is essentially just a small suite of microservices.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandytango%2Fredux-postgrest-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandytango%2Fredux-postgrest-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandytango%2Fredux-postgrest-demo/lists"}