عندما تحتاج إلى أقل عدد من الأجزاء المتحركة
أبسط برنامج Minum (راجع المزيد من عينات التعليمات البرمجية أدناه):
public class Main {
public static void main ( String [] args ) {
var minum = FullSystem . initialize ();
var wf = minum . getWebFramework ();
wf . registerPath ( GET , "" ,
r -> Response . htmlOk ( "<p>Hi there world!</p>" ));
minum . block ();
}
}يوفر إطار الويب هذا ، "Minum" ، أساسًا الحد الأدنى بالكامل لتطبيق الويب. ل TDD ، بواسطة TDD.
make test_coverage )make mutation_test )Minum هو خمسة آلاف سطر من التعليمات البرمجية - يتراوح المنافسون "الحد الأدنى" من 400000 إلى 700000 خط عند حساب تبعياتهم. لم أجد مشروعًا مشابهًا.
يتيح تطبيق النهج البسيط أسهل تصحيح الأخطاء ، والصيانة ، وخفض التكلفة الإجمالية. معظم الأطر تتداول أسرع بدءًا من التكلفة الإجمالية الأعلى. إذا كنت بحاجة إلى جودة مستدامة ، فيجب اختبار البرنامج جيدًا وتوثيقه من البداية. على سبيل المثال ، تم تمكين قدرة هذا المشروع على تحقيق هذه التغطية عالية الاختبار بشكل كبير من خلال نموذج بساطتها.
هناك بداية سريعة ، أو إذا كان لديك المزيد من الوقت ، فكر في تجربة البرنامج التعليمي
< dependency >
< groupId >com.renomad</ groupId >
< artifactId >minum</ artifactId >
< version >8.0.5</ version >
</ dependency >الحجم المترجم: 200 كيلوغرام.
خطوط رمز الإنتاج (بما في ذلك التبعيات المطلوبة)
| دقيقة | جافالين | حذاء الربيع |
|---|---|---|
| 5،335 | 141،048 | 1،085،405 |
انظر التفاصيل
انظر مقارنة الأداء الإطار
راجع الروابط التالية لمشاريع العينة التي تستخدم هذا الإطار.
أصغر
يعد هذا المشروع ذا قيمة لرؤية التطبيق الدنيا الذي يمكن تقديمه. قد تكون هذه نقطة انطلاق جيدة لاستخدام Minum في مشروع جديد.
مثال
هذا مثال جيد لرؤية مشروع أساسي له وظائف مختلفة. إنه يوضح العديد من حالات الاستخدام النموذجية لإطار Minum.
مشروع Memoria
هذا هو مشروع شجرة الأسرة. إنه يوضح نوع النهج الذي يهدف هذا الإطار إلى تعزيزه.
إنشاء قاعدة بيانات جديدة:
var db = new Db <>( foosDirectory , context , new Foo ());إضافة كائن جديد إلى قاعدة بيانات:
var foo = new Foo ( 0L , 42 , "blue" );
db . write ( foo ); تحديث كائن في قاعدة بيانات:
foo . setColor ( "orange" );
db . write ( foo ); الحذف من قاعدة بيانات:
db . delete ( foo ); كتابة بيان السجل:
logger . logDebug (() -> "hello" );تحليل وثيقة HTML:
List < HtmlParseNode > results = new HtmlParser (). parse ( "<p></p>" );البحث عن عنصر في الرسم البياني المتساوي:
HtmlParseNode node ;
List < HtmlParseNode > results = node . search ( TagName . P , Map . of ());إنشاء معالج ويب جديد (وظيفة تعالج طلب HTTP وإرجاع استجابة):
public Response myHandler ( Request r ) {
return Response . htmlOk ( "<p>Hi world!</p>" );
}تسجيل نقطة النهاية هذه:
webFramework . registerPath ( GET , "formentry" , sd :: formEntry );بناء القالب وتقديمه:
TemplateProcessor foo = TemplateProcessor . buildProcessor ( "hello {{ name }}" );
String rendered = foo . renderTemplate ( Map . of ( "name" , "world" ));الحصول على معلمة استعلام من طلب:
String id = r . requestLine (). queryString (). get ( "id" );الحصول على معلمة الجسم من طلب ، كسلسلة:
String personId = request . body (). asString ( "person_id" );احصل على معلمة مسار من طلب كسلسلة:
Pattern requestRegex = Pattern . compile ( ".well-known/acme-challenge/(?<challengeValue>.*$)" );
final var challengeMatcher = requestRegex . matcher ( request . requestLine (). getPathDetails (). isolatedPath ());
// When the find command is run, it changes state so we can search by matching group
if (! challengeMatcher . find ()) {
return new Response ( StatusLine . StatusCode . CODE_400_BAD_REQUEST );
}
String tokenFileName = challengeMatcher . group ( "challengeValue" );الحصول على معلمة جسم من طلب ، كصفيف بايت:
byte [] photoBytes = body . asBytes ( "image_uploads" );التحقق من رسالة سجل أثناء الاختبارات:
assertTrue ( logger . doesMessageExist ( "Bad path requested at readFile: ../testingreadfile.txt" ));