https://github.com/siongui/go-kit-gqlgen-postgres-todo-example
TODO example using Go kit, GraphQL/gqlgen, and PostgreSQL
https://github.com/siongui/go-kit-gqlgen-postgres-todo-example
go-kit golang gqlgen graphql postgresql
Last synced: 3 months ago
JSON representation
TODO example using Go kit, GraphQL/gqlgen, and PostgreSQL
- Host: GitHub
- URL: https://github.com/siongui/go-kit-gqlgen-postgres-todo-example
- Owner: siongui
- License: unlicense
- Created: 2022-01-27T17:13:36.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-02-19T08:40:09.000Z (over 3 years ago)
- Last Synced: 2025-04-04T15:21:25.109Z (6 months ago)
- Topics: go-kit, golang, gqlgen, graphql, postgresql
- Language: Go
- Homepage:
- Size: 504 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
Awesome Lists containing this project
README
==================================
Go GraphQL PostgreSQL Todo Example
==================================.. image:: https://img.shields.io/badge/Language-Go-blue.svg
:target: https://golang.org/.. image:: https://godoc.org/github.com/siongui/go-kit-gqlgen-postgres-todo-example?status.svg
:target: https://godoc.org/github.com/siongui/go-kit-gqlgen-postgres-todo-example.. image:: https://github.com/siongui/go-kit-gqlgen-postgres-todo-example/workflows/ci/badge.svg
:target: https://github.com/siongui/go-kit-gqlgen-postgres-todo-example/blob/master/.github/workflows/ci.yml.. image:: https://goreportcard.com/badge/github.com/siongui/go-kit-gqlgen-postgres-todo-example
:target: https://goreportcard.com/report/github.com/siongui/go-kit-gqlgen-postgres-todo-example.. image:: https://img.shields.io/badge/license-Unlicense-blue.svg
:target: https://github.com/siongui/go-kit-gqlgen-postgres-todo-example/blob/master/UNLICENSE`Go kit`_ + GraphQL_ (gqlgen_) + PostgreSQL_ + gorm_ Todo example for Go_.
Development Environment:
- `Ubuntu 20.04`_
- `Go 1.17`_.. contents:: Table of Contents
Usage
+++++After git clone this repo, generate and run server:
.. code-block:: bash
$ cd /path/to/this/repo/
# go generate GraphQL code
$ make schema_generateSee next section to run dockerized PostgreSQL. After PostgreSQL is running:
.. code-block:: bash
# database migrations
$ make database_migrations
# Run server
$ makeAfter the server is running, click on the link of log message. Now you can send
GraphQL requests via web interface.Run Dockerized PostgreSQL
+++++++++++++++++++++++++Install Docker_ and `Docker Compose`_
.. code-block:: bash
$ cd /path/to/this/repo/
$ docker-compose uppsql_ to connect to the database:
.. code-block:: bash
# Default password: changeme. Can be changed in docker-compose.yml
$ psql -h localhost -p 5432 -U postgres -d todo_db
Password for user postgres:
psql (12.9 (Ubuntu 12.9-0ubuntu0.20.04.1), server 14.1)
WARNING: psql major version 12, server major version 14.
Some psql features might not work.
Type "help" for help.todo_db=#
GraphQL Example
+++++++++++++++*getTodo* example #1:
.. code-block:: graphql
{
getTodo(id: "1") {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}*createTodo* example #1:
.. code-block:: graphql
mutation {
createTodo(
input: {
content_code: "TD001",
content_name: "my name",
description: "test",
start_date: "2022-01-23T14:20:50.52+08:00",
end_date: "2022-01-30T14:20:50.52+08:00",
status: Active}
) {
id
content_code
created_date
updated_date
}
}*createTodo* example #2:
.. code-block:: graphql
mutation {
createTodo(
input: {
content_code: "TD003",
content_name: "my content name",
description: "my content description",
start_date: "2022-01-23T14:20:50.52+08:00",
end_date: "2022-01-30T14:20:50.52+08:00",
status: Active}
) {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}*TodoPages* example:
.. code-block:: graphql
{
TodoPages(paginationInput: {count: 5, page: 1}) {
pagination_info {
total_count
total_pages
current_page
}
todos {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}
}*updateTodo* example #1:
.. code-block:: graphql
mutation {
updateTodo(
id: "1000"
input: {
content_code: "TD0031",
content_name: "my updated content name",
description: "my updated content description",
start_date: "2022-02-01T14:20:50.52+08:00",
end_date: "2022-02-02T14:20:50.52+08:00",
status: Inactive}
) {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}*updateTodo* example #2:
.. code-block:: graphql
mutation {
updateTodo(
id: "5"
input: {
content_code: "TD007",
content_name: "my updated content name2",
description: "my updated content description7",
status: Inactive}
) {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}*TodoSearch* example #1:
.. code-block:: graphql
query {
TodoSearch(
paginationInput: {count: 5, page: 1}
input:{
content_code: "00"
}
) {
pagination_info {
total_count
total_pages
current_page
}
todos {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}
}*TodoSearch* example #2:
.. code-block:: graphql
query {
TodoSearch(
paginationInput: {count: 5, page: 1}
input:{
start_date: "2022-02-06T07:11:18+08:00"
status: Inactive
}
) {
pagination_info {
total_count
total_pages
current_page
}
todos {
id
content_code
created_date
updated_date
content_name
description
start_date
end_date
status
created_by
updated_by
}
}
}Linter
++++++Two linters are used. graphql-schema-linter_ and golangci-lint_.
GraphQL Schema Linter
---------------------Use graphql-schema-linter_ for GraphQL schema linting. See
`.graphql-schema-linterrc <.graphql-schema-linterrc>`_ for linting config.To run the linter:
.. code-block:: bash
$ make graphql_schema_lint
golangci-lint
-------------Use golangci-lint_ for Go code linting. See
`.golangci.yml <.golangci.yml>`_ for linter config.To install golangci-lint:
.. code-block:: bash
$ make install_golangci_lint
To run golangci-lint:
.. code-block:: bash
$ make golangci_lint
Database Migrations
+++++++++++++++++++golang-migrate_ is used to apply database migrations.
To create migrations, install `golang-migrate CLI`_ first.
.. code-block:: bash
$ cd /path/to/this/repo/
$ migrate create -ext sql -dir migrations/ create_todo_table
migrations/20220202204515_create_todo_table.up.sql
migrations/20220202204515_create_todo_table.down.sqlEdit the ``up.sql`` and ``down.sql`` accordingly. After finish, set
**POSTGRESQL_URL** to tell migrate CLI where the database is:.. code-block:: bash
$ export POSTGRESQL_URL='postgres://postgres:changeme@localhost:5432/todo_db?sslmode=disable'
Now we apply the migrations to the database:
.. code-block:: bash
$ migrate -database ${POSTGRESQL_URL} -path migrations/ up
Check if the migrations is correctly applied:
.. code-block:: bash
# Default password: changeme. Can be changed in docker-compose.yml
$ psql -h localhost -p 5432 -U postgres -d todo_db
Password for user postgres:
psql (12.9 (Ubuntu 12.9-0ubuntu0.20.04.1), server 14.1)
WARNING: psql major version 12, server major version 14.
Some psql features might not work.
Type "help" for help.todo_db=# \dt+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+-------------------+-------+----------+------------+-------------
public | schema_migrations | table | postgres | 8192 bytes |
public | todos | table | postgres | 8192 bytes |
(2 rows)todo_db=# TABLE todos;
id | content_code | created_at | updated_at | deleted_at | content_name | description | start_date | end_date | status | created_by | updated_by
----+--------------+------------+------------+------------+--------------+-------------+------------+----------+--------+------------+------------
(0 rows)Migrations with gorm.Model
--------------------------gorm_ is ORM library for Go. The migration SQL for gorm.Model_:
.. code-block:: go
// gorm.Model embedded in MyType
type MyType struct {
gorm.Model
}The table name is *my_types*
.. code-block:: sql
CREATE TABLE "my_types"
(
"id" bigserial,
"created_at" timestamptz NOT NULL,
"updated_at" timestamptz NOT NULL,
"deleted_at" timestamptz,
PRIMARY KEY ("id")
);CREATE INDEX "idx_my_type_deleted_at" ON "my_types" ("deleted_at")
Authentication and Permission
+++++++++++++++++++++++++++++Steps to implement:
1. Get RSA Public key from http endpoint of identity provider.
2. Use gin or chi to to get the token from header, and passed the token to
gqlgen resolver.
3. Verify and extract user info and permissons from the token.- | `go - How to propagate context values from Gin middleware to gqlgen resolvers? - Stack Overflow `_
| `Providing authentication details through context — gqlgen `_
| `Using Gin to setup HTTP handlers — gqlgen `_- `GitHub - ghiden/go-kit-stringsvc2-with-jwt: Go kit: stringsvc2 with JWT `_
- `Go-kit微服务| JWT身份认证 `_
- `go-kit 微服务 身份认证 (JWT) | hwholiday `_
- `go-kit authentication - Google search `_
- `Get HTTP headers in directives/mutations · Issue #262 · 99designs/gqlgen · GitHub `_
- `laisky-blog: [Golang] 使用 gqlgen 编写 GraphQL 后端 `_
- `Using schema directives to implement permission checks — gqlgen `_
- `gqlgen data validation · GitHub `_
- `Mapping GraphQL scalar types to Go types — gqlgen `_
- `使用 GraphQL Gateway 串接多個 Data Schema - 小惡魔 - AppleBOY `_
- `GraphQL with Golang: Building a GraphQL Server with GO and MySQL | by Vishal Jain | Towards Dev `_
- `golang jwt parse rsa from url - Google search `_Code Structure
++++++++++++++app config
----------- `config/ `_: application configuration
GraphQL
-------- `gqlgen.yml `_: gqlgen config file.
- `graph/ `_: GraphQL schema, resolvers, and custom scalar.business logic
--------------- `todo/ `_: Go micro service - *todo*
- `todo/tododb/ `_: database library for *todo* service.database migrations
-------------------- `tools/migrate/ `_: command line tool for database migrations.
- `migrations/ `_: database migrations SQL files.dependency tracking
-------------------- `tools/tools.go `_: Track tool dependencies for a module.
See [2]_UNLICENSE
+++++++++Released in public domain. See UNLICENSE_.
References
++++++++++.. [1] `github.com/99designs/gqlgen `_
.. [2] | `gqlgen Quick start `_
| `How can I track tool dependencies for a module? `_
.. [3] `github.com/siongui/go-kit-url-shortener-micro-service `_
.. [4] `Building a GraphQL Server with Go Backend Tutorial | Getting Started `_
.. [5] `How To Remove Docker Images, Containers, and Volumes | DigitalOcean `_
.. [6] | `go kit graphql `_
| `GraphQL support · Issue #636 · go-kit/kit · GitHub `_
| `Add initial GraphQL support by sagikazarmark · Pull Request #81 · sagikazarmark/modern-go-application · GitHub `_
.. [7] `jinzhu/configor: Golang Configuration tool that support YAML, JSON, TOML, Shell Environment `_
.. [8] generating core failed: comment the ``autobind`` in https://gqlgen.com/config.
See `generating core failed: unable to load example/graph/model in v0.16 `_
.. [9] | `golang migrate err no change - Google search `_
| `go - golang-migrate no change error on initial migration - Stack Overflow `_
| `Migrate.Up() errors out if the latest schema is in use · Issue #100 · golang-migrate/migrate · GitHub `_
.. [10] | `Using Gin to setup HTTP handlers — gqlgen `_
| `How can i use gin with standard handlers? · Issue #57 · gin-gonic/gin · GitHub `_
| `Using http.Handler? · Issue #293 · gin-gonic/gin · GitHub `_.. _Go: https://golang.org/
.. _Go kit: https://gokit.io/
.. _GraphQL: https://graphql.org/
.. _gqlgen: https://github.com/99designs/gqlgen
.. _PostgreSQL: https://www.postgresql.org/
.. _Ubuntu 20.04: https://releases.ubuntu.com/20.04/
.. _Go 1.17: https://golang.org/dl/
.. _Docker: https://docs.docker.com/engine/install/
.. _Docker Compose: https://docs.docker.com/compose/install/
.. _psql: https://www.postgresguide.com/utilities/psql/
.. _graphql-schema-linter: https://github.com/cjoudrey/graphql-schema-linter
.. _golangci-lint: https://golangci-lint.run/
.. _golang-migrate: https://github.com/golang-migrate/migrate
.. _golang-migrate CLI: https://github.com/golang-migrate/migrate/tree/master/cmd/migrate
.. _gorm: https://gorm.io/
.. _gorm.Model: https://gorm.io/docs/models.html#gorm-Model
.. _UNLICENSE: https://unlicense.org/