(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/newsList all news with pagination
curl localhost:8080/api/v1/news?page_number=1&page_size=10List published News
curl localhost:8080/api/v1/news?status=publishList deleted News
curl localhost:8080/api/v1/news?status=deletedList draft News
curl localhost:8080/api/v1/news?status=draftList all news with pagination with status
curl localhost:8080/api/v1/news?page_number=1&page_size=10?status=draftGet 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
