Skip to content

Instantly share code, notes, and snippets.

@glinesbdev
Created February 22, 2019 06:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glinesbdev/ba39ce7c3a2f4b5f0437d6ed7980e96a to your computer and use it in GitHub Desktop.
Save glinesbdev/ba39ce7c3a2f4b5f0437d6ed7980e96a to your computer and use it in GitHub Desktop.
(Dart 2) Basic Aqueduct HTTP Controller
/// This is a very basic HTTP Controller for the Aqueduct Dart web framework
/// [https://aqueduct.io/]
import 'dart:async';
import 'dart:io';
import 'package:aqueduct/aqueduct.dart';
import 'package:faker/faker.dart';
const Faker faker = Faker();
/// [Read] is the data model
class Read {
const Read({this.id, this.title, this.author, this.year});
/// Had to use [toString()] everywhere since dart throws a
/// [The argument type 'dynamic' can't be assigned to the parameter type 'String']
/// error if we don't.
factory Read.fromMap(Map<String, dynamic> data) {
return Read(
id: int.parse(data['id'].toString()),
title: data['title'].toString(),
author: data['author'].toString(),
year: int.parse(data['year'].toString()));
}
Map<String, dynamic> toJson() =>
{"id": id, "title": title, "author": author, "year": year};
final int id;
final String title;
final String author;
final int year;
}
/// This will act as our temporary "database" for each session.
List<Map<String, dynamic>> reads = [
{
"id": 0,
"title": faker.conference.name(),
"author": faker.person.name(),
"year": faker.randomGenerator.integer(2019, min: 1999)
},
{
"id": 1,
"title": faker.conference.name(),
"author": faker.person.name(),
"year": faker.randomGenerator.integer(2019, min: 1999)
},
{
"id": 2,
"title": faker.conference.name(),
"author": faker.person.name(),
"year": faker.randomGenerator.integer(2019, min: 1999)
},
];
class ReadsController extends ResourceController {
/// List to store data from the "database".
List<Read> _data;
@override
FutureOr<RequestOrResponse> handle(Request request) {
/// Our local data list will be updated from the
/// "database" upon each request.
_data = reads.map((read) => Read.fromMap(read)).toList();
return super.handle(request);
}
@Operation.get()
Future<Response> getAllReads() async {
/// We can get the data from our local data list
/// since we don't have to change the data in any way.
return Response.ok(_data)..contentType = ContentType.json;
}
@Operation.get('id')
Future<Response> getRead(@Bind.path('id') int id) async {
String _error = '';
Read _read;
/// We can get the data from our local data list
/// since we don't have to change the data in any way.
try {
_read = _data.firstWhere((read) => read.id == id);
} catch (e) {
_error = 'Cannot find read: $e';
}
if (_error.isNotEmpty) {
return Response.notFound(body: _error);
}
return Response.ok(_read.toJson())..contentType = ContentType.json;
}
@Operation.post()
Future<Response> createNewRead() async {
/// Not sending an [id] to the server with postman since a real
/// database would do that automatically. I'm simulating that here.
final Map<String, dynamic> body = await request.body.decode()
..putIfAbsent("id", () => _data.last.id + 1);
/// Add the new data to the "database".
reads.add(body);
return Response.ok(body)..contentType = ContentType.json;
}
@Operation.put('id')
Future<Response> updateRead(@Bind.path('id') int id) async {
String _error = '';
Read _read;
int _index;
/// Not sending an id to the server with postman since a real
/// database would do that automatically. I'm simulating that here.
final Map<String, dynamic> body = await request.body.decode()
..putIfAbsent("id", () => id);
try {
_index = reads.indexWhere((read) => read['id'] == id);
} catch (e) {
_error = 'Cannot find read: $e';
}
if (_error.isNotEmpty) {
return Response.notFound(body: _error);
}
_read = Read.fromMap(body);
/// Updating the "database".
reads[_index] = _read.toJson();
final Map<String, dynamic> result = {
"message": "Updated read",
"read": _read.toJson()
};
return Response.ok(result)..contentType = ContentType.json;
}
@Operation.delete('id')
Future<Response> deleteRead(@Bind.path('id') int id) async {
String _error = '';
int _index;
/// We need to find the object from the
/// "database" and not our local data list.
try {
_index = reads.indexWhere((read) => read['id'] == id);
} catch (e) {
_error = 'Cannot find read: $e';
}
if (_error.isNotEmpty) {
return Response.notFound(body: _error);
}
/// Remove it from the "database".
reads.removeAt(_index);
return Response.ok('Deleted a read')..contentType = ContentType.json;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment