카테고리 없음
strapi customizing(2)
NOMADFISH
2020. 12. 18. 23:32
customizing을 위한 기본적인 내장 함수 설명과, strapi에 의해서 제공되는 기본 APIs 이외 개발자가 생성한 API를 어떻게 추가 하는지 설명 하도록 한다.
customizing을 위한 내장 함수 설명
module.exports = {
async find(ctx) {
let entities;
if (ctx.query._q) {
entities = await strapi.services['task'].search(ctx.query);
} else {
entities = await strapi.services['task'].find(ctx.query);
}
return entities.map(entity => {
const item = sanitizeEntity(entity, {
model: strapi.models['task'],
});
return item;
});
},
}
- 앞선 글에서 find라는 함수를 재 정의 하여, /task/[id] 형태의 find restAPI를 재정의 할 수 있다 라는 설명을 햇었고 위와 깉은 형태이다.
- 가장 먼저 보이는 것이 'strapi.services['task']' 라고 뭔가 Task라는 모듈을 획득하는 듯한 느낌이 있는데. 실제로 strapi에 내가 생성한 task collection을 운영하는 service 모듈을 가져 오는 방법이다.
- 기본적으로 orm객체를 얻어 오는 것과 같은 느낌이라고 생각 하면 된다.
- ORM은 DB를 객체화 시켜 사용하기 위해 만든 중간 mapper로 쿼리를 sql문이 아닌 함수나 객체를 이용하여 쿼리를 실행 한다. ORM이 익숙하지 않다면 검색해서 좀더 찾아 보길 권한다..
- search, find 라는 2개의 함수를 볼 수 있는데, 두 개를 사용하는 분기 점을 보면 _q라는 변수가 query(query param)에 실려 있는 경우이다.
- find: 단순한 조건만으로 아이템을 찾기가 가능하다, 예를 들어 ID가 0인경우, ID가 1 또는 0 인경우 정도
- search는 sql 쿼리문과 비슷한 수준의 아이템 찾기가 가능하다. 그만큼 문법도 복잡하다.
- 자세히 알고 싶다면 여기를 클릭해서 읽어 보길 바라며, 나중에 좀더 자세하게 예제를 통해 알아 보도록 하겟다.
- search, find로 task collection에서 찾아낸, 값들 결국 DB 쿼리를 통해 나온 row들이며, 값는 Object Array로 생성된다.
- 그렇다면 이 값을 그대로 return하면 되는데 아래 map을 해서 값을 한번 수정해 준다.
- sanitizeEntiry라는 것을 사용하는데, model 에 strapi.models['task'] 라고 넣어 준다.
- DB에서 직접 쿼리된 데이터에는 user등과 같은 노출 되면 안되느 정보나 혹은 DB 관리등을 위해서 사용되는 API로 노출 시켜봐야 쓸모 없는 데이터들이 있어서 으걸 제거해 주는 함수 이다.
- 이때 참조할 Model(DB Table 정의, 정확히 strapi에서는 collection에 정의된 fields)가 무엇인지 입력해 주어야 한다.
- map 함수내에서 값을 변경시키거나, 추가 하는 방법으로 API로 내려가는 응답값에 변경을 줄 수 있다.
새로운 함수의 적용
- 위 find 함수 말고, 새로운 함수를 하나 만들어서 이것을 API에서 사용하고 싶다면, 어떻게 하면 될지 알아 보자
- 일단 위 code는 api/task/controller/task.js 라는 이름으로 존재하는 코드에 module.exports 아래 구현하였는데, 도데체 이 API는 어떻게 restAPI로 서비스 되는 걸까?
- 우리는 nodejs에서 보통 REST API를 생성하고 만들때 보면 Express등을 사용하여, Router라는 걸로 /xxx/xx path로 Request가 들어 오면 A 함수, 혹은 객체에 mapping 해주는 방식을 많이 사용한다. 여기를 참조
Express 라우팅
라우팅 라우팅은 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식을 말합니다. 라우팅에 대한 소개는 기본 라우팅을 참조하십시오. 다음 코드는 매우 기본
expressjs.com
- 그렇다면, 위 cotroller와 연결하는 코드는 도데체 어디에 있는 것인가?
- 아래 보면 api/task/config/routers.json에 정의 되어 있다.

- task 관련 api의 router는 위 경로의 json에 정의 되어 있고, routers라는 json 객체에 path, handler가 정의되어 있음 볼 수 있다.
- Method: REST API GET, POST, PUT, DELETE중 하나
- path: routing path로 url에 나타나는
- handler: controller에 정의한 위 경로로 들어 오는 request를 처리할 handler
- config: 접근 권한이나 정책등을 정의 할 수 있다.
- 위 첨부된 그림에서 볼 수 있듯이, /tasks는 task.find라는 handler함수로 연결되있고 이는 conroller에 find라는 함수에 매핑된다. 이름에서 느낄 수 있듯이 [controller code file name].[controller function name]으로 되어있다.
- api/task/config/routes.json 파일에 task.find 핸들러는 -> api/task/controllers/task.js에 module.exports.find 함수가 된다.
- 뭔가 이름들에서 규칙이 좀 보일 것이다.
- 그런데 위 그림에서 볼 수 있는 것과 같이 find, cout이런 함수들이 매핑되 있음을 알 수 있는데, 실제로 cotroller에 정의 되어 있지 않다.
- 아래 처음 collection을 만들면 생성되는 기본 router에 달린 handler들은 일종의 내장 함수로 위에 이야기한 'strapi.services['task']' 가 가진 기본 함수라서 따로 정의 하진 않아도 된다., 위에서 find를 재정의 해서 개발자 구미대로 변경은 가능 하다.
{
"routes": [
{
"method": "GET",
"path": "/tasks",
"handler": "task.find",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/tasks/count",
"handler": "task.count",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/tasks/:id",
"handler": "task.findOne",
"config": {
"policies": []
}
},
{
"method": "POST",
"path": "/tasks",
"handler": "task.create",
"config": {
"policies": []
}
},
{
"method": "PUT",
"path": "/tasks/:id",
"handler": "task.update",
"config": {
"policies": []
}
},
{
"method": "DELETE",
"path": "/tasks/:id",
"handler": "task.delete",
"config": {
"policies": []
}
}
]
}
그렇다면 controller에 함수를 추가 하고, 여기에 위와 같은 형식으로 API를 추가 하고 controller를 연결 시키면, 새로운 strapi가 제공하는 것 이외 새로운 API를 탄생 시킬 수 있을 것이다. 이건 다음에 직접 해 보도록 하겟다.