- Architecture
- Unit & Integration Test
- Features
- Study Case
- You Can DO IT !
- Example Package
- Performance & Quality
- Trusted library
- How it works ?
- Clean setup
- Test your API
- Need your contribution
full example https://github.com/zokypesch/example-ceria with docker-compose for running environment in your local machine, CD/CI with jenkins and kubernetes soon will be updated !!!
1. API WRAPPER
2. POSTGRES & ELASTIC MIRRORING
3. RabbitMQ Wrapper
4. Redis Wrapper
5. Struct Converter and Modification
6. Http Test Helper for integration test
Imagine you must
1. create database & tables,
2. initial your project,
3. Create router,
4. Create model,
5. Create controllers
6. Testing your api & many things
So .... How long did it take to finish this from scratch ??? 3 days ??? 2 days ?? 1 days ?? 5 hours ???
Just register your struct / model, and BOOOOMMM ! your api is already to consume
SAY no to killing my time …
"Speed development is a key success for your bussiness" `Maulana`
Why choose us
because ceria is LIGHT & warm
Package in example https://github.com/zokypesch/example-ceria
- Ceria Repository (Handler like CRUD API GATEWAY)
- Ceria Core (DB Conn, Redis, RabbitMQ, Elastic)
- Ceria Util (Converting, GetValue)
- Ceria Helper (Test Helper, Wrapper)
- Docker (Environment)
- Makefile (Short hands for running your apps)
- Examples (Example how to use) <a href="https://github.com/zokypesch/example-ceria">https://github.com/zokypesch/example-ceria</a>
- Ceria using trusted library & high performance
- Ceria have UNIT & INTEGRATION TEST Coverage more than 90 %
- Ceria easly customize because it’s transparant
- Ceria core is friendly you can modified it easly
- Ceria using TDD (Test design driven)
local library :
Ceria Core
Ceria Repository(Handler Management)
Ceria Util (Utility)
Ceria Helper (Http Helper)
Ceria Wrapper
external library :
Gorm (ORM) <a href="http://gorm.io">http://gorm.io</a>
Gin (HTTP Framewrok) <a href="https://gin-gonic.github.io/gin/">https://gin-gonic.github.io/gin</a>
GIN-JWT (JWT Auth) <a href="https://github.com/appleboy/gin-jwt">https://github.com/appleboy/gin-jwt</a>
Redisstore (Redis) <a href="github.com/garyburd/redigo">github.com/garyburd/redigo</a>
Assert (Unit Testing) <a href="https://github.com/stretchr/testify">https://github.com/stretchr/testify</a>
Go-playground (Validatior) <a href="https://github.com/go-playground/validator">https://github.com/go-playground/validator</a>
GO-Mocket(Mocking SQL for Gorm) <a href="https://github.com/Selvatico/go-mocket">https://github.com/Selvatico/go-mocket</a>
Ampq (Rabbit MQ) <a href="https://github.com/streadway/amqp">https://github.com/streadway/amqp</a>
VIPER (Read Config File) <a href="github.com/spf13/viper">github.com/spf13/viper</a>
Dep (Depedency tool vendor) <a href="https://github.com/golang/dep">https://github.com/golang/dep</a>
Elastic (Elastic Library) <a href="github.com/olivere/elastic">github.com/olivere/elastic</a>
example project different repository, you can fin & clone or download example in https://github.com/zokypesch/example-ceria
type "make help" in current folder example-ceria
make init mode=development
make install_docker
make install
make rundb
see example in folder example and "go run main.go"
for full example type "cd examples/wrapper && go run main.go"
for run example rabbitMQ type "cd examples/rabbitMQ && go run main.go"
note: make sure postgresql, rabbitmq, elastic, redis run in your machine or if you want to disable please change status to false in config.development.yaml, for this version only support postgresql
mkdir example_project
dep init
dep ensure -add github.com/zokypesch/ceria
dep ensure
touch config.yaml
// edit config.yaml
mode: development
touch config.development.yaml
//edit config.development.yaml
db:
STATUS: true
PORT: 5432
DRIVER: postgres
HOST: localhost
USER: local
PASSWORD: local
NAME: local
elastic:
STATUS: true
HOST: 127.0.0.1
PORT: 9200
redis:
STATUS: true
HOST: 127.0.0.1
PORT: 6379
rabbitmq:
STATUS: true
HOST: 127.0.0.1
HOSTNAME: amqp
PORT: 5672
USER: rabbitmq
PASSWORD: rabbitmq
mkdir helper
cd helper && touch helper.go
// edit file helper.go
package helper
import (
"strconv"
ceria "github.com/zokypesch/ceria"
"github.com/zokypesch/ceria/core"
"github.com/zokypesch/ceria/helper"
hlp "github.com/zokypesch/ceria/helper"
repo "github.com/zokypesch/ceria/repository"
routeService "github.com/zokypesch/ceria/route"
)
// GetDB for get db service wrapping
func GetDB() *core.Connection {
config := helper.NewReadConfigService()
config.Init()
port, _ := strconv.Atoi(config.GetByName("db.port"))
db := core.NewServiceConnection(
config.GetByName("db.driver"),
config.GetByName("db.host"),
port,
config.GetByName("db.user"),
config.GetByName("db.password"),
config.GetByName("db.name"),
)
return db
}
// GetRouter func for get router
func GetRouter() (*routeService.GinCfg, *repo.ElasticProperties) {
config := helper.NewReadConfigService()
config.Init()
initRouter := routeService.NewRouteService(true, "./templates", false)
myElastic := &repo.ElasticProperties{}
if config.GetByName("elastic.status") == "true" {
myElastic = &repo.ElasticProperties{
Status: true,
Host: config.GetByName("elastic.host"),
Port: config.GetByName("elastic.port"),
}
}
return initRouter, myElastic
}
// GetGroup for get group default nil
func GetGroup(name string) *ceria.GroupConfiguration {
return &ceria.GroupConfiguration{
Name: name,
Middleware: nil,
}
}
// GetRabbitMQ for get configuration in rabbitMQ
func GetRabbitMQ() (*core.RabbitMQCore, error) {
config := hlp.NewReadConfigService()
config.Init()
host := config.GetByName("rabbitmq.host")
hostname := config.GetByName("rabbitmq.hostname")
port := config.GetByName("rabbitmq.port")
user := config.GetByName("rabbitmq.user")
password := config.GetByName("rabbitmq.password")
rb, errNew := core.NewServiceRabbitMQ(&core.RabbitMQConfig{
Host: host,
Hostname: hostname,
Port: port,
User: user,
Password: password,
WorkerName: "my_task",
})
return rb, errNew
}
touch main.go
// edit your main.go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/zokypesch/ceria"
hlp "github.com/zokypesch/ceria/helper"
"github.com/zokypesch/ceria/repository"
"your-directory-project/helper"
)
type Article struct {
gorm.Model
Title string `json:"title" binding:"required,max=10"`
Tag string `json:"tag"`
Body string `json:"body" binding:"required"`
}
func main() {
fmt.Println("Welcome to example ceria !")
db := helper.GetDB()
initRouter, elastic := helper.GetRouter()
grp := helper.GetGroup("")
dbs, _ := db.GetConn()
dbs.Migrate(&Article{})
ceria.RegisterModel(
initRouter,
db,
elastic,
Article{},
grp,
&repository.QueryProps{PreloadStatus: true, Preload: []string{},
WithPagination: true},
nil,
)
r, _ := initRouter.Register(true)
r.Run(":9090")
}
go run main.go
Get Data
curl -H "Accept: application/json" -X GET http://localhost:9090/articles?page=1&limit=30
Response
{"data":[{"Author":{"Fullname":"udin"},"AuthorID":"2","Body":"lorem ipsum lorem ipsum lorem ipsum","Comments":[],"Model":{"CreatedAt":"2019-01-09 05:57:16.017519 +0000 UTC","DeletedAt":"","ID":"1","UpdatedAt":"2019-01-09 05:57:16.017519 +0000 UTC"},"Tag":"#thanks","Title":"Hi there iam fine thanks"}],"error":"","message":"","page":"1","status":true,"total_data":"1"}%
Insert with inheritance
curl -i -H "Accept: application/json" -X POST http://localhost:9090/articles -d \
'{"title": "hello welcome to ceria", "tag": "#Ceriaworkspace", "body": "lorem ipsum lorem ipsum", "Author": {"fullname": "Ceria Lover"}, "Comments": [{"fullname": "udin", "body": "top numero uno"},{"fullname": "ucok", "body": "bahh layyy"}]}'
Response
{"data":{"ID":14,"CreatedAt":"2019-01-09T21:49:50.911122+07:00","UpdatedAt":"2019-01-09T21:49:50.911122+07:00","DeletedAt":null,"title":"hellowelcome to ceria","tag":"#Ceriaworkspace","body":"lorem ipsum lorem ipsum","author":{"ID":5,"CreatedAt":"2019-01-09T21:49:50.90907+07:00","UpdatedAt":"2019-01-09T21:49:50.90907+07:00","DeletedAt":null,"fullname":"Ceria Lover"},"author_id":5,"Comments":[{"ID":2,"CreatedAt":"2019-01-09T21:49:50.915091+07:00","UpdatedAt":"2019-01-09T21:49:50.915091+07:00","DeletedAt":null,"article_id":14,"fullname":"udin","body":"top numero uno"},{"ID":3,"CreatedAt":"2019-01-09T21:49:50.920292+07:00","UpdatedAt":"2019-01-09T21:49:50.920292+07:00","DeletedAt":null,"article_id":14,"fullname":"ucok","body":"bahh layyy"}]},"error":"","message":"","status":true}%
Normal insert
curl -i -H "Accept: application/json" -X POST http://localhost:9090/articles -d \
'{"title": "hello welcome to ceria", "tag": "#Ceriaworkspace", "body": "lorem ipsum lorem ipsum", "author_id": 1}'
Response
{"data":{"ID":15,"CreatedAt":"2019-01-09T21:51:10.295422+07:00","UpdatedAt":"2019-01-09T21:51:10.295422+07:00","DeletedAt":null,"title":"hellowelcome to ceria","tag":"#Ceriaworkspace","body":"lorem ipsum lorem ipsum","author":{"ID":0,"CreatedAt":"0001-01-01T00:00:00Z","UpdatedAt":"0001-01-01T00:00:00Z","DeletedAt":null,"fullname":""},"author_id":1,"Comments":null},"error":"","message":"","status":true}
Update
curl -i -H "Accept: application/json" -X PUT http://localhost:9090/articles/14 -d \
'{"data": {"title": "iam in ceria"}}'
Delete
curl -H "Accept: application/json" -X DELETE http://localhost:9090/articles/13
Response
{"data":null,"error":"","message":"","status":true}%
Bulk Delete
curl -H "Accept: application/json" -X POST http://localhost:9090/articles/bulkdelete -d \
'{"data": [{"id": 1},{"id": 2, "title": "iam in ceria"}]}'
Response
{"data":{"data":[{"id":1},{"id":2,"title":"iam in ceria"}]},"error":"","message":"","status":true}%
Bulk Create
curl -i -H "Accept: application/json" -X POST http://localhost:9090/articles/bulkcreate -d \
'[{"title": "hello welcome to ceria", "tag": "#Ceriaworkspace", "body": "lorem ipsum lorem ipsum", "author_id": 1}]'
response
{"data":[{"ID":16,"CreatedAt":"2019-01-09T21:55:18.507644+07:00","UpdatedAt":"2019-01-09T21:55:18.507644+07:00","DeletedAt":null,"title":"hello welcome to ceria","tag":"#Ceriaworkspace","body":"lorem ipsum lorem ipsum","author":{"ID":0,"CreatedAt":"0001-01-01T00:00:00Z","UpdatedAt":"0001-01-01T00:00:00Z","DeletedAt":null,"fullname":""},"author_id":1,"Comments":null}],"error":"","message":"","status":true}
Find
curl -i -H "Accept: application/json" -X POST http://localhost:9090/articles/find -d \
'{"condition": {"author_id": 3}}'
Response
{"data":[{"Author":{"Fullname":""},"AuthorID":"3","Body":"lorem ipsum lorem ipsum lorem ipsum","Comments":[],"Model":{"CreatedAt":"2019-01-09 07:02:19.743132 +0000 UTC","DeletedAt":"","ID":"9","UpdatedAt":"2019-01-09 07:02:19.743132 +0000 UTC"},"Tag":"#thanks","Title":"Hi there iam not fine thanks"}],"error":"","message":"","status":true}%
Login to get JWT
curl -i -H "Content-Type: application/json" -X POST http://localhost:9090/login -d \
'{"username": "admin","password": "admin"}'
Response
{"code":200,"expire":"2019-01-09T22:59:51+07:00","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDcwNDk1OTEsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU0NzA0NTk5MX0.T3OV4vnnGFJwwkmbkxLIlpMBUfpBJzswd8Tu3wxfaFs"}
get token and accept to barrier
curl -i -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDcwNDk1OTEsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU0NzA0NTk5MX0.T3OV4vnnGFJwwkmbkxLIlpMBUfpBJzswd8Tu3wxfaFs" -X GET http://localhost:9090/auth/comments
Response
{"data":[{"ArticleID":"12","Body":"hai udin great !","Fullname":"ajinomoto","Model":{"CreatedAt":"2019-01-09 07:08:53.706371 +0000 UTC","DeletedAt":"","ID":"1","UpdatedAt":"2019-01-09 07:08:53.706371 +0000 UTC"}},{"ArticleID":"14","Body":"top numero uno","Fullname":"udin","Model":{"CreatedAt":"2019-01-09 14:49:50.915091 +0000 UTC","DeletedAt":"","ID":"2","UpdatedAt":"2019-01-09 14:49:50.915091 +0000 UTC"}},{"ArticleID":"14","Body":"bahh layyy","Fullname":"ucok","Model":{"CreatedAt":"2019-01-09 14:49:50.920292 +0000 UTC","DeletedAt":"","ID":"3","UpdatedAt":"2019-01-09 14:49:50.920292 +0000 UTC"}}],"error":"","message":"","status":true}
check your elastic search
curl -i -H "Content-Type: application/json" -X POST http://localhost:9200/articles/_search -d '{"id": "14"}'
for query using expression like
curl -H "Accept: application/json" -X GET http://localhost:9090/articles?page=1&limit=1&where=title:welcome:LIKE|author_id:1:EQUAL
Response
{"data":[{"Author":{"Fullname":"admin"},"AuthorID":"1","Body":"lorem ipsum lorem ipsum lorem ipsum","Comments":[],"Model":{"CreatedAt":"2019-01
-09 06:24:29.73612 +0000 UTC","DeletedAt":"","ID":"8","UpdatedAt":"2019-01-09 06:24:29.73612 +0000 UTC"},"Tag":"#thanks","Title":"Hi there iam
not fine thanks"}],"error":"","message":"","page":"1","status":true,"total_data":"1"}
please contact me at [email protected]