Annotated_Shelf는 어노테이션을 사용하여 REST API를 쉽게 만들 수 있도록 도와주는 강력한 Dart 라이브러리입니다. 경로, 요청 핸들러 및 응답을 코드 어노테이션을 통해 직접 정의할 수 있는 깔끔하고 직관적인 인터페이스를 제공합니다. Shelf 프레임워크 위에 구축되어 있으며, 최소한의 반복 코드로 효율적이고 타입 안전한 API를 생성할 수 있게 해줍니다. 빠른 API 개발에 적합하며, OpenAPI/Swagger 문서와의 원활한 통합도 지원합니다. macOS, Windows, Linux에서 실행 가능하여 크로스플랫폼 백엔드 서비스에 적합합니다.
사용 사례
최소 설정으로 RESTful API 구축하기
코드에서 OpenAPI 문서 생성
백엔드 서비스의 빠른 프로토타이핑
주석을 사용하여 유형 안전한 엔드포인트 만들기
기존 Dart 프로젝트와의 통합
주요 기능
주석 기반 경로 정의
고성능을 위해 선반 위에 구축됨
자동 OpenAPI/Swagger 문서
요청/응답 모델링 지원
크로스 플랫폼 호환성
적합한 대상
Dart 개발자가 백엔드 API를 구축하고 있습니다
빠른 API 스크래핑이 필요한 팀
OpenAPI 통합이 필요한 프로젝트
선언형 코딩 스타일을 선호하는 개발자
다양한 플랫폼을 대상으로 하는 백엔드 서비스
고려 사항
Dart 주석에 익숙해야 합니다
선반 기반 서버 아키텍처에 제한됨
복잡한 라우팅을 위해 추가 구성이 필요할 수 있습니다
작은 규모에서 중간 규모의 API에 가장 적합
문서 생성은 주석의 정확성에 달려 있습니다
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Powerful, Lightweight, Fast development, Easy to learn
Annotated Shelf is a powerful and lightweight Dart framework for generating REST APIs using annotations. Based on the popular Shelf library. Annotated Shelf provides a simple and intuitive interface for building APIs fast, efficiently, and easy to use without losing what Shelf can offer.
Features
Support for multiple HTTP methods and request types.
Support for File upload.
Automatic validation of request parameters.
Automatic Error responses based on exceptions.
Installation
To install Annotated Shelf, add it as a dependency in your pubspec.yaml file:
dependencies:annotated_shelf:^0.1.0
Then, run pub get to install the package.
Getting Started
To use Annotated Shelf to create a REST API, import the library and annotate your models and controllers with the following annotations:
@RestAPI,
@GET,
@POST,
@PUT,
@DELETE,
@PATCH,
Annotated Shelf will automatically generate the necessary routes and endpoints based on the annotations you have provided.
Example
import'package:annotated_shelf/annotated_shelf.dart';
import'package:shelf/shelf.dart';
import'package:shelf/shelf_io.dart'as io;
const _hostname = 'localhost';
const _port = 8080;
var itemsList = [Item("first item"), Item("second Item")];
classItemextendsPayload{
finalString? name;
Item(this.name);
@overridefactoryItem.fromJson(Map<String, dynamic> json) {
returnItem(json["name"]);
}
@overrideMap<String, dynamic> toJson() => {"name": name};
}
classTestFormextendsForm{
String name;
int number;
File image;
TestForm(this.name, this.number, this.image);
@overridefactoryTestForm.fromJson(Map<String, dynamic> json) {
returnTestForm(
json['name'] asString,
json['number'] asint,
File.fromJson(json['image'] asMap<String, dynamic>),
);
}
@overrideMap<String, dynamic> toJson() => <String, dynamic>{
'name': name,
'number': number,
'image': image,
};
}
@RestAPI(baseUrl: '/to-do/list')
classItemsAdaptor{
@GET()
List<Item> getAllItems(Request request) {
return itemsList;
}
@GET(url: "/<itemName>")
ItemgetItemByName(String itemName) {
var index = itemsList.lastIndexWhere((element) => element.name == itemName);
if (index >= 0) {
return itemsList[index];
} else {
throwNotFoundError('item not found'); // this creates a 404 response
}
}
@PUT(url: "/<itemName>")
ItemupdateItem(Item item, String itemName) {
var index = itemsList.lastIndexWhere((element) => element.name == itemName);
if (index >= 0) {
itemsList[index] = item;
returngetItemByName(item.name ?? '');
} else {
throwNotFoundError('item not found'); // this creates a 404 response
}
}
@POST(url: "/")
ResponsecreateNewItem(Item item) {
var index =
itemsList.lastIndexWhere((element) => element.name == item.name);
if (index == -1) {
itemsList.add(item);
returnResponse(201); // pass a shelf response
} else {
throwBadRequestError('item with name in list');
}
}
// examplo of uploading a file@POST(url: '/upload')
Future<RestResponse> upload(TestForm form) async {
print(form);
returnnewRestResponse(201, {"msj": 'ok'}, "application/json");
}
}
Future<void> main(List<String> args) async {
var router = Cascade();
router = awaitmount(ItemsAdaptor(), router);
var server = await io.serve(router.handler, _hostname, _port);
print('Serving at http://${server.address.host}:${server.port}');
}
/*
-------------------------------------
mounting Instance of 'ItemsAdaptor'
adding get to-do/list
adding get to-do/list/<iteName>
adding put to-do/list/<iteName>
adding post to-do/list/
adding post to-do/list/upload
-------------------------------------
Serving at http://localhost:8080
*/
Contributing
We welcome contributions to Annotation Shelf! If you have an idea for a new feature or have found a bug, please open an issue on GitHub.
License
Annotation Shelf is released under the BSD-3-Clause. See LICENSE for details.
thanks
Special thanks to the Shelf project team for providing us with the opportunity to create servers using this beautiful language.