멋진 커뮤니티 모듈

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 POST 새 객체 만들기
/1.0/:className/:id GET 객체 읽기
/1.0/:className/:id 객체 수정
/1.0/:className/:id 삭제 객체 삭제
/1.0/:className GET 쿼리 개체 목록

새 객체 만들기

새 객체를 만들려면 객체 자체를 포함해야하는 클래스의 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" }

객체 수정

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

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

urlencode 뒤의 JSON 문자열은 where 있으며 내용은 {"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"}}
not_like 퍼지 쿼리 { "name": { "not_like": "% m"}}
사이 간격 비교 { "나이": { "사이": [22,25]}}
not_between 간격 비교 { "나이": { "not_between": [22,25]}}
안으로 열거 { "name": { "in": [ "tom", "lily"]}}
not_in 열거 { "name": { "not_in": [ "tom", "lily"]}}
또는 수술 { "또는": [{ "name": "tom"}, { "나이": 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 POST 확장 객체 생성
/1.0/:className/:id/:extendName/:rid GET 확장 객체 읽기
/1.0/:className/:id/:extendName/:rid 확장 객체 수정
/1.0/:className/:id/:extendName/:rid 삭제 확장 된 객체 삭제
/1.0/:className/:id/:extendName GET 확장 객체 목록 쿼리

확장 객체 설정

확장 된 객체를 설정하는 것은 두 개의 독립적 인 객체를 연결하는 것입니다. 예를 들어, 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
* 모두 3

권한을 검토 한 결과, 먼저 일치 id 지정되지 않은 경우 권한이 사용자의 일치, 해당 role 여전히 지정한 경우, 권한을 해당, 그것은 여부에 보이는 * 경우 권한, * 도 지정하지 않으면 권한이 없습니다.

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

권위

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

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

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

예를 들어, 위의 예에서 user titledetail 만 읽도록 설정해야하고 다른 사용자가 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 형식 클래스 다이어그램을 그리고 파일에 저장하여 다음과 유사한 이미지를 얻을 수 있습니다. 다이어그램