使用FlutterFt。DartFrog和MongoDB构建完整的堆栈应用程序。第2部分
#教程 #flutter #dart #mongodb

大家好,在上一个教程中,我们使用 dart-frog 为我们的flutter full stack pizza shop创建了API 应用。

现在我们将学习如何连接 mongodb 在飞镖蛙服务器中。

先决条件

  • MongoDB(crid知识)

  • 和DART基础知识。

注意:如果您错过了Part 1

让我们从离开的地方开始。

  • 克隆遵循github存储库
git clone git@github.com:Djsmk123/pizza_shop_dart_backend_part_1.git
  • 创建一个名为 pizza_shop 的新数据库,其收藏量 pizzas orders 如下所示。

Database and collections creation

  • 现在,将以下JSON数据添加到集合 pizzas
[
    {
        "id": "50",
        "name": "Baby Bell Peppers",
        "description": "BELL PEPPERS, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/7650vx0h.png",
        "price": 10
      },
      {
        "id": "6",
        "name": "Basil",
        "description": "BASIL LEAVES, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 11
      },
      {
        "id": "110",
        "name": "Daiya Vegan Mozzarella",
        "description":
            "FILTERED WATER, TAPIOCA FLOUR, EXPELLER PRESSED NON-GMO CANOLA AND/OR SAFFLOWER OIL, COCONUT OIL, PEA PROTEIN, SALT, VEGAN NATURAL FLAVOURS, INACTIVE YEAST, VEGETABLE GLYCERIN, XANTHAN GUM, CITRIC ACID, TITANIUM DIOXIDE",
        "price": 12,
        "image": "https://assets.zumepizza.com/public/oo9dpuia.png"
      },
      {
        "id": "74",
        "name": "Kalamata Olives",
        "description": "KALAMATA OLIVES, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/ezuum3ch.png",
        "price": 5
      },
      {
        "id": "75",
        "name": "Mushrooms",
        "description": "MUSHROOMS, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 6
      },
      {
        "id": "76",
        "name": "Onions",
        "description": "ONIONS, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/7650vx0h.png",
        "price": 7
      },
      {
        "id": "77",
        "name": "Pepperoni",
        "description": "PEPPERONI, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 8
      },
      {
        "id": "78",
        "name": "Red Onions",
        "description": "RED ONIONS, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 9
      },
      {
        "id": "79",
        "name": "Roasted Red Peppers",
        "description": "ROASTED RED PEPPERS, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 10
      },
      {
        "id": "80",
        "name": "Spinach",
        "description": "SPINACH, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 11
      },
      {
        "id": "81",
        "name": "Sun Dried Tomatoes",
        "description": "SUN DRIED TOMATOES, WATER, SEA SALT, SUNFLOWER OIL",
        "image": "https://assets.zumepizza.com/public/nfjqscxz.jpg",
        "price": 12
      }
]

pizzas.json

  • 使用订单与以下数据相同
[
   {
    "id": 1,
    "user_id": "1",
    "pizza_id": "6",
    "address": "1234 Main St",
    "phone_number": "1234567890",
    "status": "pending"
  }
]
  • 让我们在我们的项目中添加mongoDB依赖性。
   mongo_dart: ^0.8.2

添加 pubspec.yaml

  • 在名为服务的项目中创建一个新文件夹,该文件将处理MongoDB服务并创建一个名为 database_services.dart 的新文件。

// ignore_for_file: prefer_single_quotes, lines_longer_than_80_chars

import 'package:dart_frog/dart_frog.dart';
import 'package:mongo_dart/mongo_dart.dart';

class DatabaseService {
  static final db = Db("mongodb://localhost:27017/pizza_shop");
  //start the database
  static Future<void> startDb() async {
    if (db.isConnected == false) {
      await db.open();
    }
  }

  //close the database
  static Future<void> closeDb() async {
    if (db.isConnected == true) {
      await db.close();
    }
  }

  //collections
  static final pizzasCollections = db.collection('pizzas');
  static final ordersCollections = db.collection('orders');

  // we will use this method to start the database connection and use it in our routes
  static Future<Response> startConnection(
    RequestContext context,
    Future<Response> callBack,
  ) async {
    try {
      await startDb();
      return await callBack;
    } catch (e) {
      return Response.json(
        statusCode: 500,
        body: {'message': 'Internal server error'},
      );
    }
  }
}
  • 我们将使用以下查询进行数据库管理
  1. koude0:要查找给定集合的所有数据。

  2. koude1):将用来从具有指定值的给定集合中找到特定数据。

  3. koude2:将使用它将数据插入给定的集合中。

让我们编辑现有端点

  • /pizzas:我们将从“ pizzacollection”中获取所有比萨饼,并将映射到PizzaModel列表,然后返回相同的披萨。

//File name : routes/pizzas.dart


// ignore_for_file: lines_longer_than_80_chars

import 'package:dart_frog/dart_frog.dart';
import 'package:mongo_dart/mongo_dart.dart';

import '../models/pizza_models.dart';
import '../services/database_services.dart';

Future<Response> onRequest(RequestContext context) async {
  return DatabaseService.startConnection(context, getPizzas(context));
}

Future<Response> getPizzas(RequestContext context) async {
  //check if the request is a GET request
  if (context.request.method == HttpMethod.get) {
    //check if query parameter is present
    final params = context.request.uri.queryParameters;
    if (params.containsKey('id')) {
      //return the pizza with the id
      final id = params['id'];
      final doc =
          await DatabaseService.pizzasCollections.findOne(where.eq('id', id));
      if (doc != null && doc.isNotEmpty) {
        final pizza = PizzaModel.fromJson(doc);
        return Response.json(body: {'data': pizza});
      } else {
        return Response.json(
          statusCode: 404,
          body: {'message': 'Pizza not found'},
        );
      }
    } else {
      final docs = await DatabaseService.pizzasCollections.find().toList();
      final pizzas = docs.map(PizzaModel.fromJson).toList();
      return Response.json(body: {'data': pizzas});
    }
  }

  return Response.json(
    statusCode: 404,
    body: {'message': 'Method not allowed'},
  );
}

  • /fetchorders:我们将仅获取user_id在查询参数中等于user_id的文档,然后返回。

//File name fetchorders.dart

// ignore_for_file: lines_longer_than_80_chars

import 'package:dart_frog/dart_frog.dart';
import 'package:mongo_dart/mongo_dart.dart';

import '../models/order_models.dart';
import '../services/database_services.dart';

Future<Response> onRequest(RequestContext context) async {
  return DatabaseService.startConnection(context, getOrders(context));
}

Future<Response> getOrders(RequestContext context) async {
  //check if the request is a GET request
  if (context.request.method == HttpMethod.get) {
    //check if user_id is present
    final params = context.request.uri.queryParameters;
    if (params.containsKey('user_id')) {
      final userId = params['user_id'];
      final doc = await DatabaseService.ordersCollections
          .find(where.eq('user_id', userId))
          .toList();
      final userOrders = doc.map(OrderModel.fromJson).toList();
      if (userOrders.isNotEmpty) {
        return Response.json(body: {'data': userOrders.toList()});
      }
    }
    return Response.json(body: {'message': 'User id not found'});
  }
  return Response.json(
    statusCode: 404,
    body: {'message': 'Method not allowed'},
  );
}

  • /createorder:众所周知,此请求是 post ,因此我们将检查pizza_id是否有效?然后将进入orders系列的条目。

//File name createorders.dart

// ignore_for_file: avoid_dynamic_calls, noop_primitive_operations

import 'package:dart_frog/dart_frog.dart';
import 'package:mongo_dart/mongo_dart.dart';

import '../models/order_models.dart';
import '../services/database_services.dart';

Future<Response> onRequest(RequestContext context) async {
  return DatabaseService.startConnection(context, createOrder(context));
}

Future<Response> createOrder(RequestContext context) async {
  //check if the request is a POST request
  if (context.request.method == HttpMethod.post) {
    //check if headers is application/json
    final contentType = context.request.headers['content-type'];
    if (contentType == 'application/json; charset=utf-8') {
      //check if body is present
      final body = await context.request.json();

      if (body != null &&
          body['pizza_id'] != null &&
          body['user_id'] != null &&
          body['address'] != null &&
          body['phone_number'] != null) {
        //check valid pizza id

        final pizzas = await DatabaseService.pizzasCollections
            .findOne(where.eq('id', body['pizza_id']));
        final isValidPizzaId = pizzas != null && pizzas.isNotEmpty;
        if (isValidPizzaId) {
          final orders = OrderModel.fromJson({
            'id': DateTime.now().millisecondsSinceEpoch.toInt(),
            'pizza_id': body['pizza_id'],
            'user_id': body['user_id'],
            'status': 'pending',
            'address': body['address'],
            'phone_number': body['phone_number'],
          });
          await DatabaseService.ordersCollections.insert(orders.toJson());
          return Response.json(
            statusCode: 201,
            body: {
              'message':
                  'Order created successfully with order id: ${orders.id}'
            },
          );
        } else {
          return Response.json(
            statusCode: 404,
            body: {'message': 'Invalid spizza id'},
          );
        }
      } else {
        return Response.json(
          statusCode: 404,
          body: {'message': 'All fields are required'},
        );
      }
    }

    return Response.json(
      statusCode: 404,
      body: {'message': 'Content-Type must be application/json'},
    );
  }
  return Response.json(
    statusCode: 404,
    body: {'message': 'Method not allowed'},
  );
}

  • 现在您可以删除constants. dart文件。

输出

注意:我们不会在网络上构建前端,因此您可以将我的存储库用于前端。

Pizza_shop_web_application

祝大家新年快乐

meme1

我们完成了............................................

继续关注.....

关注我: