멋진 커뮤니티 모듈

fib-app

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 } ]

특수 분야

객체 데이터에는 특별한 의미를 가진 4 개의 필드가 있으며 API를 통해 변경할 수 없습니다. 그것들은 id , updatedAt , createdAt , createdBy 입니다.

id , updatedAt , createdAt 개별 필드는 자동으로 생성 및 수정됩니다. createdBy 는 자체 유형을 지정해야합니다.

기본 객체 액세스 API

이러한 데이터 정의를 완료 한 후 REST API 스펙을 준수하는 인터페이스 호출 세트를 직접 갖게됩니다.

url 방법 동작
/1.0/:className 게시하다 새 객체 만들기
/1.0/:className/:id 가져 오기 객체 읽기
/1.0/:className/:id 놓다 객체 수정
/1.0/:className/:id 지우다 객체 삭제
/1.0/:className 가져 오기 쿼리 개체 목록

새 객체 만들기

새 객체를 만들려면 객체 자체를 포함해야하는 클래스의 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 작성되며 응답 본문은 새 오브젝트의 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" }

객체 수정

객체가 가지고있는 데이터를 변경하기 위해 PUT 요청을 객체의 해당 URL로 전송할 수 있습니다. 지정하지 않은 키는 변경되지 않으므로 객체 데이터의 하위 집합 만 업데이트 할 수 있습니다. 예를 들어, 객체의 연령 필드를 변경해 보겠습니다.

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

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

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 name 두 필드 만 반환되도록 지정합니다.

필터

쿼리 개체는 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 value는 urlencode 뒤의 JSON 문자열이며 내용은 {"name":"tom"}

정확히 소정 값과 일치하는 것 외에도 where 또한 포함 같이 비교 방법을 지원한다. where 매개 변수는 다음 옵션을 지원합니다.

조작 견본
eq 같은 { "name": { "eq": "tom"}} 또는 { "name": "tom"}
ne 같지 않다 { "name": { "ne": "tom"}}
gt 이상 { "나이": { "gt": "24"}}
gte 크거나 같음 { "나이": { "gte": "24"}}
lt 이하 { "나이": { "lt": "24"}}
lte 이하 { "나이": { "lte": "24"}}
처럼 퍼지 쿼리 { "name": { "like": "% m"}}
좋아하지 않는 퍼지 쿼리 { "name": { "not_like": "% m"}}
중에서 간격 비교 { "나이": { "사이": [22,25]}}
not_between 간격 비교 { "나이": { "not_between": [22,25]}}
낱낱이 세다 { "name": { "in": [ "tom", "lily"]}}
not_in 낱낱이 세다 { "name": { "not_in": [ "tom", "lily"]}}
또는 수술 { "or": [{ "name": "tom"}, { "age": 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

이때 반환 된 결과에는 countresults 라는 두 개의 필드가 포함되며 여기에는 총 수와 결과가 각각 포함됩니다.

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은 cat이라는 애완 동물을 채택했으며 다음과 같은 조작으로 달성 할 수 있습니다.

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: String, note: 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 1
역할 사용자 그룹 이름 2
* 모두

사용 권한을 확인하는 경우, 대응하는 권한 id 처음으로 일치됩니다. 지정되지 않은 경우, 사용자에 해당하는 권한 role 일치 될 것입니다. 그것은 여전히 지정된 경우, 체크 경우 * 권한이 지정됩니다. 만약이 * 지정되지 않는 경우, 허가가 없을 것입니다.

예를 들어, 위의 권한 구성은 user 사용자 그룹을 읽을 수 있도록 지정하며, user 57fbbdb0a2400000 에는 모든 권한이 있지만 다른 사용자에게는 권한이 없습니다.

권위

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

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

권한은 액세스를 허용하려면 true 로, 액세스를 금지하려면 false 로, 지정된 필드에만 액세스를 허용하도록 array 로 설정됩니다. deletefindarray 허용하지 않습니다. array 가 설정된 경우 true 로 간주됩니다. 지정된 권한이 존재하지 않으면 동일한 주제의 * 권한과 일치합니다. 존재하지 않으면 다음 우선 순위의 주제를 다시 조회하십시오.

예를 들어, 위의 예에서 titledetail 읽기만 허용하도록 user 를 설정해야하고 다른 사용자가 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'] } } }

개체 권한

전체 클래스의 권한은 모델에서 설정되며 특정 개체에 대한 권한을 설정해야하는 경우 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); };

이 정의에서 누구나 개인 정보의 namesex 확인하고 자신의 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 형식 클래스 다이어그램을 그리고 파일에 저장하여 다음과 유사한 이미지를 얻을 수 있습니다. 도표