{"id":13652956,"url":"https://github.com/manishrjain/gocrud","last_synced_at":"2026-03-12T05:33:24.874Z","repository":{"id":57528042,"uuid":"37695407","full_name":"manishrjain/gocrud","owner":"manishrjain","description":"Go framework to simplify CRUD of structured data using Graph operations","archived":false,"fork":false,"pushed_at":"2019-03-01T00:20:42.000Z","size":542,"stargazers_count":305,"open_issues_count":7,"forks_count":22,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-23T06:36:29.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/manishrjain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-19T01:42:33.000Z","updated_at":"2025-02-19T17:23:35.000Z","dependencies_parsed_at":"2022-09-07T15:41:23.869Z","dependency_job_id":null,"html_url":"https://github.com/manishrjain/gocrud","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/manishrjain/gocrud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manishrjain%2Fgocrud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manishrjain%2Fgocrud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manishrjain%2Fgocrud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manishrjain%2Fgocrud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manishrjain","download_url":"https://codeload.github.com/manishrjain/gocrud/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manishrjain%2Fgocrud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30416310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T04:41:02.746Z","status":"ssl_error","status_checked_at":"2026-03-12T04:40:12.571Z","response_time":114,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-08-02T02:01:04.359Z","updated_at":"2026-03-12T05:33:24.858Z","avatar_url":"https://github.com/manishrjain.png","language":"Go","funding_links":[],"categories":["`API Frameworks`","Servers","Go","API Frameworks"],"sub_categories":["Go"],"readme":"# gocrud\nGo framework to simplify creating, reading, updating, and deleting arbitrary depth structured data — to make building REST services fast and easy.\n\n * [Gocrud Presentation](https://go-talks.appspot.com/github.com/manishrjain/gocrud/presentation/gomeetup.slide)\n * [Link to blog posts](https://mrjn.xyz/categories/gocrud/)\n * [Example Usage](example.md)\n\n[![wercker status](https://app.wercker.com/status/08406d64ea74cab2dd8155944e56b87d/m \"wercker status\")](https://app.wercker.com/project/bykey/08406d64ea74cab2dd8155944e56b87d)\n[![GoDoc](https://godoc.org/github.com/manishrjain/gocrud?status.svg)](https://godoc.org/github.com/manishrjain/gocrud)\n\n## Releases\n\nNote that the master branch always refers to latest version of Gocrud, which would contain breaking changes.\n**To use stable version of Gocrud APIs, please use the packages released via gopkg.in.**\n\nGocrud version | Install instructions | Godoc | Source\n:---: | --- | --- | ---\n**v1** (stable) | `go get -v gopkg.in/manishrjain/gocrud.v1/...` |  [godoc](http://godoc.org/gopkg.in/manishrjain/gocrud.v1) | [source](https://github.com/manishrjain/gocrud/tree/v1)\n**master** (dev) | `go get -v github.com/manishrjain/gocrud/...` | [godoc](https://godoc.org/github.com/manishrjain/gocrud) | [source](https://github.com/manishrjain/gocrud)\n\n\n## Questions / Support\nI primarily use IRC on freenode network. Channel is `#gocrud`. I'm `mrjn` on the network.\n[#gocrud on freenode](http://webchat.freenode.net?channels=%23gocrud\u0026uio=d4)\n\nI also hang out at the gophers.slack.com, at `#gocrud` channel.\nAlthough, Slack doesn't have a linux client which is what my workstation runs, and hence, I prefer IRC over Slack.\nYou can get an invitation to join Slack via this link:\n[Gopher Slack Signup](http://bit.ly/go-slack-signup).\nYou can also direct message me, my user id is `@manishrjain`.\n\n## Why?\n![](allthings.jpg)\n\n\u003csub\u003eCourtesy: Monish, co-founder karma.wiki\u003c/sub\u003e\n\nHaving built over 3 different startup backends, I think a lot of time is wasted figuring out and coding CRUD for data structures. In addition, the choice of database has to be made up front, which causes a lot of headache for startup founders. Gocrud was written with the aim to make CRUD easy, and provide the flexibility to switch out both the underlying storage and search engines at any stage of development.\n\n#### Data stores\nDatastore | Driver Available | Status\n--- | :---: | ---\nLevelDB | Yes | Ready\nMySQL | Yes | Needs to implement `Iterate` func\nPostgreSQL | Yes | Needs to implement `Iterate` func\nCassandra | Yes | Ready\nMongoDB | Yes | Needs to implement `Iterate` func\nGoogle Datastore | Yes | Needs to implement `Iterate` func\nRethinkDB | Yes | Needs to implement `Iterate` func\nAmazon DynamoDB | No | Needs work\n**[Datastore usage](datastore.md)** shows how to use and initialize various datastores. One can add support for more by implementing this interface:\n```go\ntype Store interface {\n  Init(args ...string)\n  Commit(its []*x.Instruction) error\n  IsNew(subject string) bool\n  GetEntity(subject string) ([]x.Instruction, error)\n  Iterate(fromId string, num int, ch chan x.Entity) (int, error)\n}\n```\n\n#### Search engines\nSearch Engine | Drive Available\n--- | :---:\nElastic Search | Yes\nSolr | No\n\nCan be added by implementing these interfaces:\n```go\ntype Engine interface {\n\tInit(args ...string)\n\tUpdate(x.Doc) error\n\tNewQuery(kind string) Query\n}\n\ntype Query interface {\n\tLimit(num int) Query\n\tOrder(field string) Query\n\tRun() ([]x.Doc, error)\n  // and few others\n}\n```\n\n## Framework\nThis framework is built to follow these principles:\n\n1. **Versioning**: Keep track of all edits to the data, including deletion operations.\n1. **Authorship**: Be able to track who edited (/deleted) what.\n1. **Retention**: On deletion, only mark it as deleted. Never actually delete any data.\n\nThe framework makes it easy to have *Parent-Child* relationships, quite common in today’s CRUD operations. For e.g.\n```\n- Posts created by User (User -\u003e Post)\n- Comments on Posts (Post -\u003e Comment)\n- Likes on Posts (Post -\u003e Like)\n- Likes on Comments (Comment -\u003e Like)\n```\nAnd be able to traverse these relationships and retrieve all of the children, grandchildren etc. For e.g. `(User -\u003e Post -\u003e [(Comment -\u003e Like), Like])`\n\nThe framework does this by utilizing Graph operations, but without using a Graph database. This means the framework can be used to quickly build a Go backend to serve arbitrarily complex data, while still using your database of choice. See [example usage](example.md)\n\n## Dependency management\nUsers who import Gocrud into their packages are responsible to organize\nand maintain all of their dependencies to ensure code compatibility and build\nreproducibility. Gocrud makes no direct use of dependency management tools like\n[Godep](https://github.com/tools/godep).\n\n## Performance considerations\nFor the [example](example.md), this is what gets stored in the database:\n```\nmysql\u003e select * from instructions;\n+------------+--------------+-----------+--------------------------------------+-----------+---------------------+---------+----+\n| subject_id | subject_type | predicate | object                               | object_id | nano_ts             | source  | id |\n+------------+--------------+-----------+--------------------------------------+-----------+---------------------+---------+----+\n| uid_oNM    | User         | Post      | NULL                                 | wClGp     | 1435408916326573229 | uid_oNM |  1 |\n| wClGp      | Post         | body      | \"You can search for cat videos here\" |           | 1435408916326573229 | uid_oNM |  2 |\n| wClGp      | Post         | tags      | [\"search\",\"cat\",\"videos\"]            |           | 1435408916326573229 | uid_oNM |  3 |\n| wClGp      | Post         | url       | \"www.google.com\"                     |           | 1435408916326573229 | uid_oNM |  4 |\n| wClGp      | Post         | Like      | NULL                                 | kStx9     | 1435408916341828408 | uid_qB3 |  5 |\n| kStx9      | Like         | thumb     | 1                                    |           | 1435408916341828408 | uid_qB3 |  6 |\n| wClGp      | Post         | Comment   | NULL                                 | 8f78r     | 1435408916341828408 | uid_qB3 |  7 |\n| 8f78r      | Comment      | body      | \"Comment by on the post\"             |           | 1435408916341828408 | uid_qB3 |  8 |\n| wClGp      | Post         | Like      | NULL                                 | Gyd7G     | 1435408916352622582 | uid_a30 |  9 |\n| Gyd7G      | Like         | thumb     | 1                                    |           | 1435408916352622582 | uid_a30 | 10 |\n| 8f78r      | Comment      | Like      | NULL                                 | q2IKK     | 1435408916357443075 | uid_I5u | 11 |\n| q2IKK      | Like         | thumb     | 1                                    |           | 1435408916357443075 | uid_I5u | 12 |\n| 8f78r      | Comment      | Comment   | NULL                                 | g8llL     | 1435408916357443075 | uid_I5u | 13 |\n| g8llL      | Comment      | body      | \"Comment xv on comment\"              |           | 1435408916357443075 | uid_I5u | 14 |\n| q2IKK      | Like         | Comment   | NULL                                 | oaztb     | 1435408916368908590 | uid_SPX | 15 |\n| oaztb      | Comment      | body      | \"Comment kL on Like\"                 |           | 1435408916368908590 | uid_SPX | 16 |\n| 8f78r      | Comment      | censored  | true                                 |           | 1435408916377065650 | uid_D2g | 17 |\n| kStx9      | Like         | _delete_  | true                                 |           | 1435408916384422689 | uid_2a5 | 18 |\n+------------+--------------+-----------+--------------------------------------+-----------+---------------------+---------+----+\n18 rows in set (0.00 sec)\n```\n\nThe writes are in constant time, where each (entity,predicate) constitutes one row. As the properties per entity grow, more rows need to be read (1 row = 1 edge/predicate) to get the entity, it's predicates and it's children. This however, shouldn't be much of a concern for any standard data, which has limited number of predicates/properties per entity. Gocrud in addition, retrieves all children in parallel via `goroutines`, instead of retrieving them one by one.\n\nProperty value filtering, sorting, full and partial text matching are now being made available via various search engines. Gocrud provides a search interface, which provides the most common search functionality right out of the box. Thus, there's a clear distinction between data store and search right from the beginning.\n\n## Reserved keywords\nThe following predicates are reserved by the framework, and shouldn't be used by the caller. Currently, this guideline isn't being hardly enforced by the framework.\n\nPredicate | Meaning\n--- | ---\n`_parent_` | Stores an edge from child -\u003e parent entity.\n`_delete_` | Marks a particular entity as deleted.\n\n## Contact\nFeel free to [contact me](https://twitter.com/manishrjain) at my Twitter handle **@manishrjain** for any discussions related to this framework. Also, feel free to send pull requests, they're welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanishrjain%2Fgocrud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanishrjain%2Fgocrud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanishrjain%2Fgocrud/lists"}