apig is an RESTful API server generator.
- Input: Model definitions based on gorm annotated struct
- Output: RESTful JSON API server using gin including tests and documents
Go 1.16 or higher is required.
After installing required version of Go, you can build and install apig
by
$ go get -d -u github.com/shimastripe/apig
$ cd $GOPATH/src/github.com/shimastripe/apig
$ make
$ make install
make
generates binary into bin/apig
.
make install
put it to $GOPATH/bin
.
First, creating by apig new
command.
$ apig new -u shimastripe apig-sample
generates Golang API server boilerplate under $GOPATH/src/github.com/shimastripe/apig-sample
.
apig supports two database engines; SQLite (sqlite
) and PostgreSQL (postgres
) and Mysql (mysql
). You can specify this by -d, -database
option.
Available command line options of apig new
command are:
Option | Description | Required | Default |
---|---|---|---|
-d, -database |
Database engine | sqlite |
|
-n, -namespace |
Namespace of API | (empty) | |
-u, -user |
Username | github username | |
--vcs |
VCS | github.com |
Second, write model definitions under models/. For example, user and email model is like below:
// models/user.go
package models
import "time"
type User struct {
ID uint `gorm:"primary_key;AUTO_INCREMENT" json:"id" form:"id"`
Name string `json:"name" form:"name"`
Emails []Email `json:"emails" form:"emails"`
CreatedAt *time.Time `json:"created_at" form:"created_at"`
UpdatedAt *time.Time `json:"updated_at" form:"updated_at"`
}
// models/email.go
package models
type Email struct {
ID uint `gorm:"primary_key;AUTO_INCREMENT" json:"id" form:"id"`
UserID uint `json:"user_id" form:"user_id"`
Address string `json:"address" form:"address"`
User *User `json:"user form:"user`
}
This models are based on gorm structure. Please refer gorm document to write detailed models.
Third, run the command:
apig gen
It creates all necessary codes to provide RESTful endpoints of models.
Finally, just build as normal go code.
$ go mod init
$ go mod tidy
$ go build -o bin/server
After that just execute the server binary.
For the first time, you may want to use AUTOMIGRATE=1
when running the server.
$ AUTOMIGRATE=1 bin/server
When AUTOMIGRATE=1
, the db tables are generated automatically.
After that, you can run the server just executing the command:
$ bin/server
The server runs at http://localhost:8080.
By default, use the port 8080. If you change the port, set environment variables.
$ PORT=3000 bin/server
The server runs at http://localhost:3000.
new
command tells apig to generate API server skeleton.
$ apig new NAME
gen
command tells apig to generate files (routes, controllers, documents...) from gorm model files you wrote.
You MUST run this command at the directory which was generated by new
command.
$ apig gen
API Documents are generated automatically in docs/
directory in the form of API Blueprint.
docs
├── email.apib
├── index.apib
└── user.apib
Aglio is an API Blueprint renderer. Aglio can be installed by
$ npm install -g aglio
You can generate HTML files and run live preview server.
// html file
$ aglio -i index.apib -o index.html
// running server on localhost:3000
$ aglio -i index.apib --server
index.apib
includes other files in your blueprint.
Each resource has 5 RESTful API endpoints. Resource name is written in the plural form.
Endpoint | Description | Example (User resource) |
---|---|---|
GET /<resources> |
List items | GET /users List users |
POST /<resources> |
Create new item | POST /users Create new user |
GET /<resources>/{id} |
Retrieve the item | GET /users/1 Get the user which ID is 1 |
PUT /<resources>/{id} |
Update the item | PUT /users/1 Update the user which ID is 1 |
DELETE /<resources>/{id} |
Delete the item | DELETE /users/1 Delete the user which ID is 1 |
Parameter | Description | Default | Example |
---|---|---|---|
fields= |
Fields to receive | All fields | name,emails.address |
preloads= |
Nested resources to preload | (empty) | emails,profile |
pretty= |
Prettify JSON response | false |
true |
Parameter | Description | Default | Example |
---|---|---|---|
stream= |
Return JSON in streaming format | false |
true |
q[field_name]= |
A unique query parameter for each field for filtering | (empty) | q[id]=1,2,5 , q[admin]=true&q[registered]=true |
sort= |
Retrieves a list in order of priority. + or (none) : ascending. - : descending |
(empty) | id , -age , id,-created_at |
limit= |
Maximum number of items | 25 |
50 |
page= |
Page to receive | 1 |
3 |
last_id= |
Beginning ID of items | (empty) | 1 |
order= |
Order of items | desc |
asc |
v= |
API version | (empty) | 1.2.0 |
API server accepts the form of JSON
or Form
.
application/json
$ curl -X POST http://localhost:8080/resources \
-H "Content-type: application/json" \
-d '{"field":"value"}'
application/x-www-form-urlencoded
$ curl -X POST http://localhost:8080/users \
-d 'field=value'
multipart/form-data
$ curl -X POST http://localhost:8080/users \
-F 'field=value'
Response data type is always application/json
.
API server supports 2 pagination types.
Retrieve items by specifying page number and the number of items per page.
For example:
http://example.com/api/users?limit=5&page=2
+---------+---------+---------+---------+---------+---------+---------+
| ID: 5 | ID: 6 | ID: 7 | ID: 8 | ID: 9 | ID: 10 | ID: 11 |
+---------+---------+---------+---------+---------+---------+---------+
| |
Page 1 ->|<-------------------- Page 2 ------------------->|<- Page 3
Response header includes Link
header.
Link: <http://example.com/api/users?limit=5&page=3>; rel="next",
<http://example.com/api/users?limit=5&page=1>; rel="prev"
Retrieve items by specifying range from a certain point.
For example:
http://example.com/api/users?limit=5&last_id=100&order=desc
+---------+---------+---------+---------+---------+---------+---------+
| ID: 94 | ID: 95 | ID: 96 | ID: 97 | ID: 98 | ID: 99 | ID: 100 |
+---------+---------+---------+---------+---------+---------+---------+
| 5 items (ID < 100) |
|<------------------------------------------------|
Response header includes Link
header.
Link: <http://example.com/api/users?limit=5&last_id=95&order=desc>; rel="next"
API server uses Semantic Versioning for API versioning.
There are 2 methods to specify API version.
Generally we recommend to include API version in Accept
header.
Accept: application/json; version=1.0.0
You can also include API version in URL parameter. This is userful for debug on browser or temporary use,
http://example.com/api/users?v=1.0.0
This method is prior to request header method.