README ¶
GoREST | RESTful API Starter kit
GoREST is a starter kit, written in Golang with Gin framework, for rapid prototyping and developing a RESTful API. The source code is released under the MIT license and is free for any personal or commercial project.
Updates
v1.3.0 [Dec 28 - 2021]
- refactored config files to reduce cyclomatic complexity
- organized instance variables
v1.2.7 [Dec 27 - 2021]
- REDIS database driver and test endpoints added
- removed ineffectual assignments
- check errors during binding of incoming JSON
v1.2.6 [Dec 26 - 2021]
v1.2.5 [Dec 25 - 2021]
- new endpoint added for refreshing JWT tokens
v1.2.4 [Aug 02 - 2021]
- middleware added:
logrus
+sentry.io
v1.2.3 [Jul 31 - 2021]
- Route handlers modified to meet the requirements of doing unit test
v1.2.2 [Jul 29 - 2021]
- Replaced
github.com/dgrijalva/jwt-go
withgithub.com/golang-jwt/jwt
Package github.com/dgrijalva/jwt-go <= v3.2.0
allows attackers to bypass
intended access restrictions in situations with []string{} for m["aud"]
(which is allowed by the specification).
More on this: https://github.com/advisories/GHSA-w73w-5m7g-f7qc
v1.2.1 [Jun 19 - 2021]
SHA-256
is replaced byArgon2id
for password hashing
v1.2.0 [Jun 17 - 2021]
GORM
updated fromv1
tov2
Projects developed based on GORM v1
must checkout at v1.1.3
v1.1 [Jan 03 - 2021]
- PostgreSQL and SQLite3 drivers are included
charset
updated fromutf8
toutf8mb4
in order to fully support UTF-8 encoding for MySQL database
v1.0 [Dec 26 - 2020]
- JWT based authentication is implemented using dgrijalva/jwt-go
One-to-one
,one-to-many
, andmany-to-many
models are introduced
Database Support
GoREST uses GORM as its ORM. GORM supports SQLite3, MySQL, PostgreSQL and Microsoft SQL Server.
In GoREST, MySQL, PostgreSQL and SQLite3 drivers are included. Anyone experienced in Microsoft SQL Server is welcome to contribute to the project by including SQL Server driver and testing all the features of GoREST.
Demo
For demonstration, a test instance can be accessed here from a web browser. For API development, it is recommended to use Postman or any other similar tool.
Accessible endpoints of the test instance:
- https://goapi.pilinux.me/api/v1/users
- https://goapi.pilinux.me/api/v1/users/:id
- https://goapi.pilinux.me/api/v1/posts
- https://goapi.pilinux.me/api/v1/posts/:id
- https://goapi.pilinux.me/api/v1/hobbies
To prevent abuse, only HTTP GET
requests are accepted by the demo server.
Setup and start the production-ready app
- Install a relational database (MySQL or PostgreSQL)
- Set up an environment to compile the Go codes (a quick tutorial for any Debian based OS)
- Install
git
- Clone the project
git clone https://github.com/piLinux/GoREST.git
- At the root of the cloned repository
[
cd $GOPATH/src/github.com/pilinux/gorest
], executego build
to fetch all the dependencies - Edit
.env.sample
file and save it as.env
file at the root of the project$GOPATH/src/github.com/pilinux/gorest
- Edit the
.env.sample
file located at$GOPATH/src/github.com/pilinux/gorest/database/migrate
and save it as.env
- Inside
$GOPATH/src/github.com/pilinux/gorest/database/migrate
, rungo run autoMigrate.go
to migrate the database- Comment the line
setPkFk()
inautoMigrate.go
file if the driver is not MySQL. Check issue: 7
- Comment the line
- At
$GOPATH/src/github.com/pilinux/gorest
, run./gorest
to launch the app
Note For SQLite3:
DBUSER
,DBPASS
,DBHOST
andDBPORT
environment variables should be left unchanged.DBNAME
must contain the full path and the database file name; i.e,
/user/location/database.db
To the following endpoints GET
, POST
, PUT
and DELETE
requests can be sent:
- http://localhost:port/api/v1/register
POST
[create new account]
{
"Email":"...@example.com",
"Password":"..."
}
- http://localhost:port/api/v1/login
POST
[generate new JWT]
{
"Email":"...@example.com",
"Password":"..."
}
- http://localhost:port/api/v1/refresh
POST
[generate new JWT]
{
"RefreshJWT":"use_existing_valid_refresh_token"
}
- http://localhost:port/api/v1/users
GET
[get list of all registered users along with their hobbies and posts]POST
[add user info to the database, requires JWT for verification]
{
"FirstName": "...",
"LastName": "..."
}
PUT
[edit user info, requires JWT for verification]
{
"FirstName": "...",
"LastName": "..."
}
- http://localhost:port/api/v1/users/:id
GET
[fetch hobbies and posts belonged to a specific user]
- http://localhost:port/api/v1/users/hobbies
PUT
[add a new hobby, requires JWT for verification]
{
"Hobby": "..."
}
- http://localhost:port/api/v1/posts
GET
[fetch all published posts]POST
[create a new post, requires JWT for verification]
{
"Title": "...",
"Body": "... ..."
}
- http://localhost:port/api/v1/posts/:id
GET
[fetch a specific post]PUT
[edit a specific post, requires JWT for verification]
{
"Title": "...",
"Body": "... ..."
}
DELETE
[delete a specific post, requires JWT for verification]- http://localhost:port/api/v1/hobbies
GET
[fetch all hobbies created by all users]
For REDIS
- Set environment variable
ACTIVATE_REDIS=yes
- Set
key:value
pairPOST
http://localhost:port/api/v1/playground/redis_create
{
"Key": "test1",
"Value": "v1"
}
- Fetch
key:value
pairGET
http://localhost:port/api/v1/playground/redis_read
{
"Key": "test1"
}
- Delete
key:value
pairDELETE
http://localhost:port/api/v1/playground/redis_delete
{
"Key": "test1"
}
- Set hashes with key
POST
http://localhost:port/api/v1/playground/redis_create_hash
{
"Key": "test2",
"Value":
{
"Value1": "v1",
"Value2": "v2",
"Value3": "v3",
"Value4": "v4"
}
}
- Fetch hashes by key
GET
http://localhost:port/api/v1/playground/redis_read_hash
{
"Key": "test2"
}
- Delete a key
DELETE
http://localhost:port/api/v1/playground/redis_delete_hash
{
"Key": "test2"
}
Flow diagram
Features
- GoREST uses Gin as the main framework, GORM as the ORM and GoDotEnv for environment configuration
- golang-jwt/jwt is used for JWT authentication
- sentry.io error tracker and performance monitor is enabled by default
as a hook inside
logrus
. They are included as middleware which can be disabled by omitting
router.Use(middleware.SentryCapture(configure.Logger.SentryDsn))
- All codes are written and organized following a straightforward and easy-to-understand approach
- For Logger and Recovery, Gin's in-built middlewares are used
router := gin.Default()
- Cross-Origin Resource Sharing (CORS) middleware is located at lib/middleware
router.Use(middleware.CORS())
- Included relationship models are:
one to one
one to many
many to many
Logical Database Model
Architecture
List of files
gorest
│---README.md
│---LICENSE
│---CONTRIBUTING.md
│---CODE_OF_CONDUCT.md
│---.gitignore
│---.env.sample
│---go.mod
│---go.sum
│---main.go
│
└───config
│ └---config.go
│ └---database.go
│ └---logger.go
│ └---security.go
│ └---server.go
│
│───controller
│ └---render.go
│ └---auth.go
│ └---login.go
│ └---user.go
│ └---post.go
│ └---hobby.go
│ └---playground.go
│
└───database
│ │---dbConnect.go
│ │
│ └───migrate
│ │ └---autoMigrate.go
│ │ └---.env.sample
│ │
│ └───model
│ └---auth.go
│ └---user.go
│ └---post.go
│ └---hobby.go
│ └---userHobby.go
│
└───lib
│ └───middleware
│ └---cors.go
│ └---jwt.go
│ └---sentry.go
│
└───logs
│ └---README.md
│
└───service
└---auth.go
└---common.go
For API development, one needs to focus mainly on the following files and directories:
gorest
│---main.go
│
│───controller
│ └---auth.go
│ └---login.go
│ └---user.go
│ └---post.go
│ └---hobby.go
│ └---playground.go
│
└───database
│ │
│ └───migrate
│ │ └---autoMigrate.go
│ │
│ └───model
│ └---auth.go
│ └---user.go
│ └---post.go
│ └---hobby.go
│ └---userHobby.go
│
└───service
└---auth.go
└---common.go
Step 1
model
: This package contains all the necessary models. Each file is responsible for one specific table in the database. To add new tables and to create new relations between those tables, create new models, and place them in this directory. All newly created files should have the same package name.
Step 2
controller
: This package contains all functions to process all related incoming HTTP requests.
Step 3
autoMigrate.go
: Names of all newly added models should first be included in this file to automatically create the complete database. It also contains the function to delete the previous data and tables. When only newly created tables or columns need to be migrated, first disabledb.DropTableIfExists()
function before executing the file.
Step 4
middleware
: All middlewares should belong to this package.
Step 5 (final step)
- Create new routes inside
v1 := router.Group()
{
...
...
}
Contributing
Please see CONTRIBUTING to join this amazing project.
Code of conduct
Please see this document.
License
© Mahir Hasan 2019 - 2022
Released under the MIT license
Documentation ¶
There is no documentation for this package.