์๋ ,
GET ์์ฒญ์ ๊ธด URL์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ผ๋ถ "์ฐพ๊ธฐ" ์ฟผ๋ฆฌ์์ ๊ธด ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํ์ฌ ์๋ฃจ์ ์ ์๋ก์ด ๋ฏธ๋ค์จ์ด์ ๋ฉ์๋ ์ฌ์ ์๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค.
// allow x-http-method-override header for GET methods
exports.default = function (req, res, next) {
if (req.headers['x-http-method-override'] === 'GET' && req.method === 'POST') {
req.method = 'GET';
req.query = req.body;
delete req.body;
}
next();
};
๊ทธ๋ฐ ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ๋ด ์๋น์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
await awesomeService.create(
{
someParam: aVeryLongArray // will replace req.query server side thanks to the middleware, and thus bypass URL limitations of browsers
},
{
headers: {
"x-http-method-override": "GET" // tell the server that this is actually a GET request, so it triggers our middleware
}
}
);
Slack์ ๋ํ ๋์์ ์ฃผ์ Sebastian์๊ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค(Github ํธ๋ค์ ์ฐพ์ ์ ์์ต๋๋ค).
์ด SO ๋ต๋ณ์ ๋ฐ๋ฅด๋ฉด POST HTTP ๋จ์ด๋ ์์ฑ ์์ฒด์ ๊ตญํ๋์ง ์๊ณ ๋ถ๋ฅํ ์ ์๋ ๋ค๋ฅธ ์ข ๋ฅ์ ์์ ๊ณผ๋ ๊ด๋ จ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ ํจํ ํจํด ์ ๋๋ค. ๋ฐ๋ผ์ "๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ์ฐพ๊ธฐ"๋ POST์ ๊ด๋ จ ์ฌ์ฉ ์ฌ๋ก๋ก ๊ฐ์ฃผ๋ ์ ์์ต๋๋ค.
ํ์ง๋ง... ๋ฌธ์ ๋ Feathers์์ POST ์์ฒญ์ด "์์ฑ" ์์
๊ณผ ๊ฐํ๊ฒ ์ฐ๊ฒฐ๋์ด ์๋ค๋ ๊ฒ์
๋๋ค. REST ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ ๋ ์ด๋ create
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ฉฐ, ์ด๋ ๋ฐฉํด๊ฐ ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๊ณ ์๋ฒ ์ธก์์๋ create
ํํฌ์ ๊ด๋ จ ๊ถํ์ ์ค์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๋ฐฉํด.
GET ์์ฒญ์์ body
๋๋ data
ํ๋๋ฅผ ์ง์ํ๋๋ก ์ ์ํฉ๋๋ค(๋ฐ๋ผ์ get
๋ฐ find
๋ฉ์๋). ๋๋ ๊ตฌํ์ด ์ฌ์ํ๋ค๊ณ ์๊ฐํ์ง๋ง (PR์ ๊ธฐ๋ปํ ๊ฒ์
๋๋ค), ๊ทธ๋ฌ๋ ์ ๋ ๊ถ๊ธํฉ๋๋ค.
data
๋๋ body
ํ๋๋ฅผ ์คํฌ๋ฉํ ์ ์์ต๋๊น?)body
๋งค๊ฐ๋ณ์, data
๋งค๊ฐ๋ณ์?)REST ํด๋ผ์ด์ธํธ๋ฅผ ์ข ๋ ์ ์ฐํ๊ฒ ๋ง๋ค์ด ์ฌ์ฉ์ ์ ์๋ ํด๋ผ์ด์ธํธ ์๋น์ค๋ฅผ ๋ณด๋ค ์ฝ๊ฒ โโ์ธ์คํด์คํํ ์ ์๋๋ก ํ๋ ค๊ณ ํฉ๋๋ค. JSON์ ์ฌ์ฉํ์ฌ POST ์ฟผ๋ฆฌ๋ฅผ ํ์ฉํ๋ฉด ๋ชจ๋ URL ๋ฌธ์์ด ๋ณํ ๋ฐ ๋ฐฐ์ด ๊ตฌ๋ฌธ ๋ถ์ ์ ํ๋ ํผํ ์ ์์ต๋๋ค. ํ์ฌ ํด๋ผ์ด์ธํธ์์ REST ์๋น์ค๋ฅผ ์ฌ์ฉ์ ์ง์ ํ๋ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(์ด๊ฒ์ด ๋ค๋ฅธ ๋์ ์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด๊ธฐ๋ ํฉ๋๋ค).
const FetchService = require('@feathersjs/rest-client/lib/fetch');
class MyFetchService extends FetchService {
get (id, params = {}) {
if (typeof id === 'undefined') {
return Promise.reject(new Error(`id for 'get' can not be undefined`));
}
return this.request({
url: this.makeUrl({}, id),
method: 'POST',
data: params.query,
headers: Object.assign({
'x-http-method-override': 'GET'
}, params.headers)
}, params).catch(toError);
}
}
app.use('/someservice', new MyFetchService({
connection: window.fetch,
name: 'someservice',
base: 'mybaseUrl',
options: {}
}));
ํต์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ๋ค์์ ๊ฐ๋ฅํ๊ฒ ํ ์ ์์ต๋๋ค.
const feathers = require('@feathersjs/feathers');
const rest = require('@feathersjs/rest-client');
const app = feathers();
// Connect to the same as the browser URL (only in the browser)
app.configure(rest({
base: '/',
Service: MyFetchService
}));
์๋ ํ์ธ์, ์ ๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ฐพ๊ธฐ ์์ฒญ์ด ์ฌ๋ฌ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์๋ค์ผ ์ ์์ด์ผ ํ๊ณ URL ์ ํ์ ๋๋ฌํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋์ POST๋ฅผ ์ํํ๊ณ "๋ง๋ค๊ธฐ" ๋์ "์ฐพ๊ธฐ"๋ก ๋ผ์ฐํ ํ ์ ์๋์ง ํ์ธํ๊ธฐ ์ํด ๊ณ ์ฌํ๊ณ ์์ต๋๋ค.
HTTP ์์ฒญ ๋ฉ์๋ ์ ํ์ POST์์ GET์ผ๋ก ์ฌ์ ์ํ์ฌ @eric-burel์ด ์ ์ํ ๊ฒ์ ์๋ํ์ง๋ง "์ฐพ๊ธฐ"๋ก ๋ผ์ฐํ ํ๋ ๋์ ์๋น์ค์์ "๋ง๋ค๊ธฐ" ๋ฉ์๋๋ฅผ ์ฐพ๋ ๋ฐ ์คํจํ์ต๋๋ค. ์์ฒญ ๊ฐ์ฒด ๋ฉ์๋๊ฐ ์ค์ ๋ก "GET"์ผ๋ก ๋ณ๊ฒฝ๋๋ ๊ฒ์ ํ์ธํ์ง๋ง ์ด ๋ณ๊ฒฝ ์ ์ ํ๋ ๋ผ์ฐํ ์ด ๋ฐ์ํ์ง ์์๊น์?
app.use('/์ฝ์', function(req, res, next) {
if (req.method === 'POST') { // ์ด ์๋น์ค์ ๋ํด์๋ง ์ํํฉ๋๋ค.
req.method = '๊ฐ์ ธ์ค๊ธฐ';
req.query = req.body;
req.body ์ญ์ ;
}
๋ค์();
}, {
์ฐพ๊ธฐ: ํจ์(๋งค๊ฐ๋ณ์, ์ฝ๋ฐฑ) {
// ๋ญ๊ฐ๋ฅผ ํ๋ค
}
});
์ฌ๊ธฐ์์ ๋ด๊ฐ ๋์น๊ณ ์๋ ๋ถ๋ถ์ด ์๋์ง ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น? ๋๋ ๋ ๋์ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
์ด๊ฒ์ v5์ ๋์ค๋ ์๋ก์ด ์ฌ์ฉ์ ์ ์ ๋ฐฉ๋ฒ(https://github.com/feathersjs/feathers/issues/1976)์์ ์ํํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
REST ํด๋ผ์ด์ธํธ๋ฅผ ์ข ๋ ์ ์ฐํ๊ฒ ๋ง๋ค์ด ์ฌ์ฉ์ ์ ์๋ ํด๋ผ์ด์ธํธ ์๋น์ค๋ฅผ ๋ณด๋ค ์ฝ๊ฒ โโ์ธ์คํด์คํํ ์ ์๋๋ก ํ๋ ค๊ณ ํฉ๋๋ค. JSON์ ์ฌ์ฉํ์ฌ POST ์ฟผ๋ฆฌ๋ฅผ ํ์ฉํ๋ฉด ๋ชจ๋ URL ๋ฌธ์์ด ๋ณํ ๋ฐ ๋ฐฐ์ด ๊ตฌ๋ฌธ ๋ถ์ ์ ํ๋ ํผํ ์ ์์ต๋๋ค. ํ์ฌ ํด๋ผ์ด์ธํธ์์ REST ์๋น์ค๋ฅผ ์ฌ์ฉ์ ์ง์ ํ๋ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(์ด๊ฒ์ด ๋ค๋ฅธ ๋์ ์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด๊ธฐ๋ ํฉ๋๋ค).
ํต์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ๋ค์์ ๊ฐ๋ฅํ๊ฒ ํ ์ ์์ต๋๋ค.