멋진 커뮤니티 모듈

fib 앱

fibjs 애플리케이션 기본 API 프레임워크

설치하다

1
npm install fib-app [--save]

시험

1
npm test

기본 스크립트 생성

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
const http = require('http'); const util = require('util') const Session = require('fib-session') const App = require('../'); var app = new App('sqlite:test.db', { uuid: true }); app.db.use(require('./defs/person')); var session = new Session(new util.LruCache(20000), { timeout: 60 * 1000 }); var svr = new http.Server(8080, [ session.cookie_filter, { '/1.0': app } ]); svr.run();

person모델 정의 모듈은 어디에 있으며 내용은 다음과 같습니다.

1 2 3 4 5 6 7
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }); };

이는 표준 ORM 정의이며 유형 검사, 이벤트 등과 같은 다른 ORM 기능을 사용할 수도 있습니다.

API 데이터 형식

POST 및 PUT 요청의 경우 요청 본문은 JSON 형식이어야 하며 HTTP 헤더의 Content-Type을 application/json으로 설정해야 합니다.

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person/57fbbdb0a2400000

모든 요청의 응답 형식은 JSON 개체입니다.

요청의 성공 여부는 HTTP 상태 코드로 표시됩니다. 2XX 상태 코드는 성공을 나타내고, 4XX 상태 코드는 요청이 실패했음을 나타냅니다. 요청이 실패하면 응답 본문은 여전히 ​​JSON 개체이지만 디버깅에 사용할 수 있는 코드와 메시지 필드가 항상 포함됩니다. 예를 들어, 권한 인증 요청이 실패하면 다음 정보가 반환됩니다.

1 2 3 4
{ "code": 4030501, "message": "The operation isn’t allowed for clients due to class-level permissions." }

코드 코드는 세 부분으로 나누어지며, 처음 세 자리인 403은 오류 유형을 나타내고, 05는 데이터 시트 번호, 01은 세부 오류 코드를 나타냅니다.

GET 요청의 경우 일반적으로 객체 데이터를 반환하는데, GET 요청의 주소에 따라 객체 또는 배열을 반환할 수 있습니다. 예를 들어:

1 2 3 4 5
{ "name": "tom", "sex": "male", "age": 23 }

또는:

1 2 3 4 5 6 7 8 9 10 11 12
[ { "name": "tom", "sex": "male", "age": 23 }, { "name": "lily", "sex": "female", "age": 22 } ]

특수 분야

객체 데이터에는 API를 통해 변경이 허용되지 않는 특별한 의미를 지닌 4개의 필드가 있습니다. 각각 id, updatedAt, createdAt입니다 createdBy.

그 중 id, updatedAt, createdAt단일 필드가 자동으로 생성 및 수정됩니다. createdBy유형을 직접 지정해야 합니다.

기본 객체 액세스 API

이러한 데이터 정의를 완료하면 REST API 사양을 준수하는 일련의 인터페이스 호출을 직접 갖게 됩니다.

URL 방법 행동
/1.0/:클래스이름 우편 새 개체 만들기
/1.0/:클래스이름/:id 얻다 객체 읽기
/1.0/:클래스이름/:id 놓다 개체 수정
/1.0/:클래스이름/:id 삭제 개체 삭제
/1.0/:클래스이름 얻다 쿼리 개체 목록

새 개체 만들기

새 객체를 생성하려면 객체 자체를 포함하는 클래스의 URL로 POST 요청을 보내야 합니다. 예를 들어 위에 표시된 객체를 생성하려면 다음을 수행합니다.

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person

생성이 성공하면 HTTP 반환은 201 Created이고 응답 본문은 새 객체의 objectId 및 CreatedAt 타임스탬프를 포함하는 JSON 객체입니다.

1 2 3 4
{ "createdAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

객체 읽기

객체를 생성할 때 반환된 헤더의 위치에 GET 요청을 보내 해당 콘텐츠를 검색할 수 있습니다. 예를 들어 위에서 만든 객체를 얻으려면 다음을 수행하십시오.

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000

반환된 본문은 모든 사용자 제공 필드와 createdAt, updatedAtid필드를 포함하는 JSON 개체입니다.

1 2 3 4 5 6 7 8
{ "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

반환 필드를 설정하면 다음으로 구분된 필드 이름 문자열 keys반환된 콘텐츠를 맞춤설정할 수 있습니다 .keys,

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000?keys=name%2Csex

다음을 반환합니다:

1 2 3 4
{ "name": "tom", "sex": "male" }

개체 수정

객체의 기존 데이터를 변경하려면 객체의 해당 URL로 PUT 요청을 보내면 됩니다. 지정하지 않은 키는 변경되지 않으므로 객체 데이터의 하위 집합만 업데이트할 수 있습니다. 예를 들어 객체의 age 필드를 변경해 보겠습니다.

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"age": 25}' \ http://localhost/1.0/person/57fbbdb0a2400000

반환된 JSON 객체 에는 업데이트가 발생한 시기를 나타내는 필드가 updatedAt포함 됩니다 .id

1 2 3 4
{ "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

개체 삭제

객체를 삭제하려면 지정된 객체의 URL에 DELETE 요청을 보낼 수 있습니다. 예를 들면 다음과 같습니다.

1
curl -X DELETE http://localhost/1.0/person/57fbbdb0a2400000

쿼리 개체 목록

URL 매개변수 없이 클래스의 URL에 GET 요청을 보내면 여러 객체를 한 번에 가져올 수 있습니다. 모든 사용자를 간단히 얻는 방법은 다음과 같습니다.

1
curl -X GET http://localhost/1.0/person

반환된 값은 결과 필드를 포함하는 JSON 개체이며, 해당 값은 개체 목록입니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }, { "name": "lily", "sex": "female", "age": 22, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400001" } ]

키 필드 사용자 정의

개체 쿼리와 마찬가지로 keys목록 쿼리 시 설정하여 반환된 결과에 포함되는 필드를 사용자 지정할 수 있습니다. keys콘텐츠는 ,로 구분된 필드 이름 문자열입니다. 예를 들면 다음과 같습니다.

1
curl -X GET http://localhost/1.0/person?keys=name%2Cage

nameage필드만 반환되도록 지정합니다 .

여기서 필터 조건

where쿼리 객체는 매개변수 형태 로 제한될 수 있습니다.

where매개변수 값은 JSON으로 인코딩되어야 합니다. 즉, 실제 URL 요청이 이루어지는 것을 보면 먼저 JSON으로 인코딩한 다음 URL로 인코딩해야 합니다. 매개변수를 사용하는 가장 간단한 where방법은 적절한 키와 값을 포함하는 것입니다. 예를 들어, tom이라는 사용자를 검색하려면 다음과 같이 쿼리를 구성합니다.

1
curl -X GET http://localhost/1.0/person?where=%7B%22name%22%3A%22tom%22%7D

where값은 urlencoded JSON 문자열이며 내용은 다음과 같습니다.{"name":"tom"}

주어진 값을 정확하게 일치시키는 것 외에도 where포함(inclusion)과 같은 비교 방법도 지원됩니다. where매개변수는 다음 옵션을 지원합니다.

열쇠 작업 견본
eq 동일한 {"이름":{"eq":"tom"}} 또는 {"이름":"tom"}
같지 않음 {"이름":{"ne":"톰"}}
gt 그 이상 {"나이":{"gt":"24"}}
gte 크거나 같음 {"나이":{"gte":"24"}}
lt 미만 {"나이":{"lt":"24"}}
LTE 보다 작거나 같음 {"나이":{"lte":"24"}}
좋다 퍼지 쿼리 {"이름":{"좋아요":"%m"}}
같지 않은 퍼지 쿼리 {"이름":{"not_like":"%m"}}
~ 사이 간격 비교 {"나이":{"사이":[22,25]}}
not_between 간격 비교 {"나이":{"not_between":[22,25]}}
~에 낱낱이 세다 {"이름":{"in":["톰","백합"]}}
not_in 낱낱이 세다 {"이름":{"not_in":["톰","백합"]}}
또는 OR 연산 {"또는":[{"이름":"톰"},{"나이":24}]}

건너뛰기 기록 건너뛰기

옵션을 통해 skip지정된 레코드 수를 건너뛰어 페이지 넘김 효과를 얻을 수 있습니다.

1
curl -X GET http://localhost/1.0/person?skip=100

한도는 기록 한도를 반환합니다.

limit옵션을 통해 반환되는 레코드 수를 제한할 수 있습니다. limit유효한 숫자는 1~1000이고 기본값은 100입니다.

1
curl -X GET http://localhost/1.0/person?limit=100

order는 정렬 방법을 지정합니다.

반환되는 결과 집합의 정렬 방법을 설정하는 옵션을 사용하며 order, 필드 이름 앞에 필드 이름이 포함되어 있으면 -역순으로 표시됩니다.

1
curl -X GET http://localhost/1.0/person?order=-id

count는 총 결과 수를 반환합니다.

요청 시 증가됨 count지정된 콘텐츠를 반환하는 동안 반환될 수 있는 총 결과 집합 수입니다.

1
curl -X GET http://localhost/1.0/person?count=1&limit=1

이때 반환된 결과에는 각각 총 수와 결과가 포함된 두 개의 필드, count및 가 포함됩니다.results

1 2 3 4 5 6 7 8 9 10 11 12 13
{ "count": 2, "results": [ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" } ] }

확장 객체 생성

ORM을 통해 hasOne 및 hasMany를 정의하면 객체 간의 연관을 정의하고 이를 API에 반영할 수 있습니다. 예를 들면 다음과 같습니다.

1 2 3 4 5 6 7 8 9
module.exports = db => { var Person = db.models.person; var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

확장된 객체 액세스 API

다음은 확장 개체의 API 정의입니다.

URL 방법 행동
/1.0/:className/:id/:extendName 놓다 확장 개체 설정
/1.0/:className/:id/:extendName 우편 확장 객체 생성
/1.0/:className/:id/:extendName/:rid 얻다 확장 객체 읽기
/1.0/:className/:id/:extendName/:rid 놓다 확장 개체 수정
/1.0/:className/:id/:extendName/:rid 삭제 확장 개체 삭제
/1.0/:className/:id/:extendName 얻다 확장 개체 목록 쿼리

확장 개체 설정

확장 개체를 설정하는 것은 두 개의 독립적인 개체 간의 관계를 설정하는 것입니다. 예를 들어 Tom이 고양이라는 이름의 애완동물을 입양한 경우 이를 달성하기 위해 다음 작업을 사용할 수 있습니다.

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"id": "57fbbdb0a2400007"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

호출 시 고양이의 ID를 본문에 지정해야 합니다.

확장 객체 생성

확장 개체를 직접 생성하면 개체를 생성하는 동안 개체 간 연결을 설정할 수 있습니다. 예를 들어:

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "cat"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

고양이라는 애완동물이 생성되어 톰과 연결됩니다.

확장 객체 읽기

확장 개체를 읽는 것은 기본 개체를 읽는 것과 매우 유사하며 다음과 같은 키 옵션도 지원합니다.

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

확장 개체 수정

확장 개체를 읽는 것은 기본 개체를 읽는 것과 매우 유사합니다.

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "cat 1"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

확장 개체 삭제

확장된 개체를 삭제하면 개체 자체가 삭제되지 않고 개체 간의 관계만 해제됩니다.

1
curl -X DETELE http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

확장 개체 목록 쿼리

확장 개체 목록 쿼리는 기본 개체 목록 쿼리와 매우 유사하며 키 및 조건부 필터링과 같은 옵션도 지원합니다.

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets

ACL

모델의 ACL을 정의하여 데이터 권한을 제어할 수 있습니다. 예를 들어:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
const orm = require('fib-orm'); module.exports = db => { db.define('blog', { title: String, detail: Stringnote: String }, { ACL: function(session) { return { "*": { "*": false }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": true } } }; } }); };

모델을 정의할 때 ACL을 지정하지 않으면 기본 권한을 설정하는 것과 같습니다.

1 2 3 4 5
{ "*": { "*": true } }

본체

ACL 주제 설명에는 세 가지 유형이 있습니다. user id, user role*id특정 사용자를 나타내고 role특정 역할을 가진 사용자를 나타내며 *모든 사용자를 나타냅니다.

본체 설명하다 우선 사항
ID 특정 사용자 ID 1
역할 사용자 그룹 이름 2
* 모두

id권한을 확인할 때 해당 권한을 먼저 일치시키고 , 지정하지 않은 role경우 사용자의 해당 권한을 일치시키고, 여전히 지정되어 있으면 *권한이 지정되어 있는지 확인하고 *, 지정하지 않으면 권한이 없는 것입니다.

예를 들어, 위의 권한 구성에서 user사용자 그룹은 읽기가 가능하도록 지정되어 있는데, 해당 사용자는 57fbbdb0a2400000모든 권한을 가지지만 다른 사용자는 어떤 권한도 가지지 않습니다.

권한

ACL은 API 동작에 따라 권한을 5가지 범주로 분류합니다.

권한 설명하다 허용되는 유형
만들다 객체 생성 참/거짓/배열
읽다 객체 읽기 참/거짓/배열
쓰다 개체 수정 참/거짓/배열
삭제 개체 삭제 허위 사실
찾다 쿼리 개체 목록 허위 사실
* 모든 권한 일치 참/거짓/배열

true액세스를 허용하고, false액세스를 거부하고, array지정된 필드에 대한 액세스만 허용하도록 권한이 설정됩니다 . 허용되지 않으며 delete설정된 경우 동일하게 처리됩니다 . 지정한 권한이 존재하지 않는 경우, 동일한 주체의 권한을 매칭합니다. 둘 다 없으면 다음 우선순위 수준의 주제를 다시 쿼리하십시오.findarrayarraytrue*

예를 들어, 위의 예에서 user읽기만 설정 title하고 detail다른 사람은 읽을 수 있도록 허용 해야 하는 경우 title다음과 같이 설정할 수 있습니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14
{ "*": { "*": false, "read": ['title'] }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": ['title', 'detail'] } } }

객체 권한

Model에 설정된 권한은 전체 클래스의 권한이며, 특정 객체에 대한 권한을 설정해야 하는 경우 OACL을 설정하면 됩니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }, { ACL: function(session) { return { "*": { "*": false } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true }; return _acl; } }); };

이 예에서는 방문자가 객체 자신인 경우 모든 작업이 허용되고, 그렇지 않으면 모든 액세스가 금지됩니다. 권한은 다음과 같이 확인됩니다.

  • person[57fbbdb0a2400000]=>OACL
  • person=>ACL

확장된 객체 권한

확장 개체의 액세스 권한 제어는 기본 개체의 권한과 유사하지만 ACL을 별도로 지정해야 한다는 점만 다릅니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
module.exports = db => { var Person = db.define('person', { name: String, sex: ["male", "female"], age: Number },{ ACL: function(session) { return { "*": { "read": ['name', 'sex'], "extends": { "pets": { "read": true, "find": true } } } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true, "extends": { "pets": { "*": true } } }; return _acl; } }); var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

name이 정의에 따르면, 개인정보의 총합은 누구나 확인할 수 sex있고, 자유롭게 확인, 검색할 수 있으며 pets, 이용자 스스로가 자신의 모든 데이터를 운영할 수 있고, 자신의 반려동물 정보에 대한 모든 권한을 가질 수 있습니다.

확장 개체에 대한 접근 권한을 확인할 때 개체 권한과 확장 개체 권한을 별도로 확인합니다. 예를 들어 다음 요청은 다음과 같습니다.

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

권한은 다음과 같이 확인됩니다.

  • pets[57fbbdb0a2400007]=>OACL
  • person[57fbbdb0a2400000]=> OACL=> extends=>pets
  • person=> ACL=> extends=>pets
  • pets=>ACL

기능

모델에 대해 API를 정의할 수 있으며, 사용자 정의 함수를 통해 복잡한 데이터 작업을 완료할 수 있습니다.

대부분의 권한은 ACL을 통해 제어할 수 있으며 객체 기반 권한은 함수를 통해 구현할 필요가 없습니다. 승인 상태에 따라 다양한 사용자 그룹에 권한을 부여하는 등 데이터 기반 권한을 완료하는 데 기능을 사용할 수 있습니다. 그리고 여러 데이터베이스 레코드를 수정해야 하는 등의 여러 수정이 필요합니다.

데이터 모델 그리기

app.diagram()데이터 정의를 완료한 후 데이터 모델의 형식 클래스 다이어그램을 그리는 데 사용할 수 있습니다 svg. 파일에 저장하면 다음과 유사한 이미지를 얻게 됩니다. 도표