(a try) Implementation of Domain Design Driven (DDD) on a news website (News, Topics and Tags)
This was for technical test of a company in Jakarta.
Mandatory:
- A News could have many topics and tags
- When list (a) news will show the related topics and tags
- News can have status: draft, deleted and publish
- List all topics
- List all tags
- Filter news based on topics
- Filter news based on tags
Optional:
- Support pagination when getting all news
- TBD
cp .env_example .env
docker system prune --force
docker volume rm godddnews_postgresql godddnews_postgresql_data --force
docker-compose build
docker-compose up -d
-
Mandatory: Create REST API News & Tag CRUD
- News
- Get all
- Get news by its status
- Get news by its topic
- Get news by its tag
- Get news by pagination
- Get by slug
- Get by id
- Get by topic
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- Get all
- Topic
- Get all
- Get by slug
- Get by id
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- Tag
- Get all
- Get by slug
- Get by id
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- News
-
Mandatory: API Functional Test (see interfaces/handlers/handler_test)
- News
- Get all
- Get news by its status
- Get news by its topic
- Get news by its tag
- Get news by pagination
- Get by slug
- Get by id
- Get by topic
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- Get all
- Topic
- Get all
- Get by slug
- Get by id
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- Tag
- Get all
- Get by slug
- Get by id
- Create
- Update
- Update by id
- Update by slug
- Delete
- Delete by id
- Delete by slug
- News
- Create User Stories
- Design the database as per requirement:
- Relationship (Primary & Foreign Key)
- Indexing
- News Versioning (for optimistic lock versioning)
- Create model/struct as domain
- Create repository layer
- Create layer/service layer
- Json validation
- Error management
- Api version management
- Activity Logging (ToDo)
- Handling duplicate requests (ToDo)
- Development Stacks:
- Golang: GoChi, logrus
- Gorm: hard delete, many2many
- DB: Postgre
- Migration: Auto Migration
- Deployment:
- Docker & Docker compose
GET
: Get all newsPOST
: Create a news
GET
: Get all news by its status
GET
: Get all news with pagination
GET
: Get a news by idPUT
: Update a news by idDELETE
: Delete a news by id
GET
: Get a news by slugPUT
: Update a news by slugDELETE
: Delete a news by slug
GET
: Get all news by topic slug
GET
: Get all news by tag slug
GET
: Get all topicPOST
: Create a topic
GET
: Get a topic by idPUT
: Update a topic by idDELETE
: Delete a topic by id
GET
: Get a topic by slug-namePUT
: Update a topic by slug-nameDELETE
: Delete a topic by slug-name
GET
: Get all tagPOST
: Create a tag
GET
: Get a tag by idPUT
: Update a tag by idDELETE
: Delete a tag by id
GET
: Get a tag by slug-namePUT
: Update a tag by slug-nameDELETE
: Delete a tag by slug-name
Create News without ID
curl --request POST \
--url "localhost:8080/api/v1/news" \
--header 'content-type: application/json' \
--data '{
"title": "Shalat berjamaah",
"slug": "cara-shalat",
"content": "Cara shalat khusyu sesuai sunnah",
"status": "publish",
"topic_slugs": ["religion","national"],
"tag_slugs":["other-tag","national-tag"]
}'
Create News with ID
curl --request POST \
--url "localhost:8080/api/v1/news" \
--header 'content-type: application/json' \
--data '{
"id":10,
"title": "Makan murah dan kenyang",
"slug": "cara-makan-kenyang",
"content": "Cara makan kenyang dan murah",
"status": "draft",
"topic_slugs": ["other-topic","national"],
"tag_slugs":["international-tag","national-tag"]
}'
List all news
curl localhost:8080/api/v1/news
List all news with pagination
curl localhost:8080/api/v1/news?page_number=1&page_size=10
List published News
curl localhost:8080/api/v1/news?status=publish
List deleted News
curl localhost:8080/api/v1/news?status=deleted
List draft News
curl localhost:8080/api/v1/news?status=draft
List all news with pagination with status
curl localhost:8080/api/v1/news?page_number=1&page_size=10?status=draft
Get news by its slug
curl --request GET --url "localhost:8080/api/v1/news/cara-makan-kenyang"
Get news by its id
curl --request GET --url "localhost:8080/api/v1/news/10"
Update news by its id
curl --request PUT --url "localhost:8080/api/v1/news/10" --header 'content-type: application/json' --data \
'{
"title": "Dialog antar warga",
"slug": "dialog-warga",
"content": "Dialog antar warg membuktikan bahwa jiwa masyarakat Indonesia masih mementingkan musyawarah.",
"status": "publish",
"topic_slugs": ["politics", "national"],
"tag_slugs": ["other-tag", "national-tag"]
}'
Get news by topic's slug
curl --request GET --url "localhost:8080/api/v1/news/topic/politics"
Get news by tag's slug
curl --request GET --url "localhost:8080/api/v1/news/tag/other-tag"
Delete news by its id
curl --request DELETE --url "localhost:8080/api/v1/news/10"
Create a topic
curl --request POST \
--url "localhost:8080/api/v1/topic" \
--header 'content-type: application/json' \
--data '{
"id": 10,
"name": "Hobi Berenang",
"slug": "hobi-berenang"}'
Get a topic by slug
curl --request GET --url "localhost:8080/api/v1/topic/hobi-berenang"
Update topic by slug
curl --request PUT \
--url "localhost:8080/api/v1/topic/hobi-berenang" \
--header 'content-type: application/json' \
--data '{
"name": "Hobi Berenang Aja",
"slug": "hobi-berenang-aja"}'
Delete topic by slug
curl --request DELETE --url "localhost:8080/api/v1/topic/hobi-berenang-aja"
Get topic by id
curl --request GET --url "localhost:8080/api/v1/topic/1"
Update topic by id
curl --request PUT \
--url "localhost:8080/api/v1/topic/3" \
--header 'content-type: application/json' \
--data '{
"name": "Hobi Membaca aja",
"slug": "hobi-membaca"}'
Delete topic by id
curl --request DELETE --url "localhost:8080/api/v1/topic/3"
Create a tag
curl --request POST \
--url "localhost:8080/api/v1/tag" \
--header 'content-type: application/json' \
--data '{
"id": 10,
"name": "Hobi Berenang",
"slug": "hobi-berenang"}'
Get a tag by slug
curl --request GET --url "localhost:8080/api/v1/tag/hobi-berenang"
Update tag by slug
curl --request PUT \
--url "localhost:8080/api/v1/tag/hobi-berenang" \
--header 'content-type: application/json' \
--data '{
"name": "Hobi Berenang Aja",
"slug": "hobi-berenang-aja"}'
Delete tag by slug
curl --request DELETE --url "localhost:8080/api/v1/tag/hobi-berenang-aja"
Get tag by id
curl --request GET --url "localhost:8080/api/v1/tag/1"
Update tag by id
curl --request PUT \
--url "localhost:8080/api/v1/tag/3" \
--header 'content-type: application/json' \
--data '{
"name": "Hobi Membaca aja",
"slug": "hobi-membaca"}'
Delete tag by id
curl --request DELETE --url "localhost:8080/api/v1/tag/3"
Up
migrate -database "postgres://root:root@localhost:54322/godddnews_db?sslmode=disable" -path migration/scripts/ up
Down
migrate -database "postgres://root:root@localhost:54322/godddnews_db?sslmode=disable" -path migration/scripts/ down
Version
migrate -database "postgres://root:root@localhost:54322/godddnews_db?sslmode=disable" -path migration/scripts/ version
- To enable logging on DB query and log, comment the "PRODUCTION_ENV" in .env
author: [email protected]/Depok/Indonesia
- Gochi router: https://github.com/go-chi/chi/blob/master/_examples/rest/main.go
- DB Migration: https://github.com/golang-migrate/migrate
- DDD Skeleton : https://github.com/takashabe/go-ddd-sample
- DDD Implementation : https://github.com/jojoarianto/go-ddd-api
- GORM Documentation : http://doc.gorm.io
- API test: https://github.com/steinfletcher/apitest