diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42e78d1..6b87ea3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [8.0.0] - 2024-07-01
 ### Added
-- CORS middware
+- CORS middleware
 
 ### Changed
 - Bump http\_interop to v2.0
diff --git a/example/server.dart b/example/server.dart
index a8173b4..ab13f03 100644
--- a/example/server.dart
+++ b/example/server.dart
@@ -1,14 +1,13 @@
 import 'dart:io';
 
-import 'package:http_interop/http_interop.dart' as interop;
-import 'package:json_api/document.dart';
-import 'package:json_api/http.dart';
+import 'package:http_interop_middleware/http_interop_middleware.dart';
 import 'package:json_api/routing.dart';
 import 'package:json_api/server.dart';
 import 'package:uuid/uuid.dart';
 
 import 'server/in_memory_repo.dart';
 import 'server/json_api_server.dart';
+import 'server/logger_middleware.dart';
 import 'server/repository.dart';
 import 'server/repository_controller.dart';
 
@@ -18,21 +17,11 @@ Future<void> main() async {
   final repo = InMemoryRepo(['colors']);
   await initRepo(repo);
   final controller = RepositoryController(repo, Uuid().v4);
-  interop.Handler handler =
-      ControllerRouter(controller, StandardUriDesign.matchTarget).handle;
-
-  handler = tryCatchMiddleware(handler,
-      onError: ErrorConverter(onError: (e, stack) async {
-        stderr.writeln(e);
-        stderr.writeln(stack);
-        return response(500,
-            document: OutboundErrorDocument(
-                [ErrorObject(title: 'Internal Server Error')]));
-      }).call);
-
-  handler = loggingMiddleware(handler,
-      onRequest: (r) => print('${r.method} ${r.uri}'),
-      onResponse: (r) => print('${r.statusCode}'));
+
+  final handler = errorConverter()
+      .add(loggerMiddleware)
+      .call(router(controller, StandardUriDesign.matchTarget));
+
   final server = JsonApiServer(handler, host: host, port: port);
 
   ProcessSignal.sigint.watch().listen((event) async {
diff --git a/example/server/logger_middleware.dart b/example/server/logger_middleware.dart
new file mode 100644
index 0000000..86e0827
--- /dev/null
+++ b/example/server/logger_middleware.dart
@@ -0,0 +1,20 @@
+import 'dart:io';
+
+import 'package:http_interop_middleware/http_interop_middleware.dart';
+
+/// Middleware that logs all requests and responses to stderr.
+final Middleware loggerMiddleware = middleware(
+  onRequest: (r) async {
+    stderr.writeln(r);
+    return null;
+  },
+  onResponse: (r, _) async {
+    stderr.writeln(r);
+    return null;
+  },
+  onError: (e, t, _) async {
+    stderr.writeln(e);
+    stderr.writeln(t);
+    return null;
+  },
+);
diff --git a/lib/http.dart b/lib/http.dart
index 9a3ced9..9adb5b2 100644
--- a/lib/http.dart
+++ b/lib/http.dart
@@ -1,69 +1 @@
-import 'package:http_interop/http_interop.dart';
-
-class StatusCode {
-  const StatusCode(this.value);
-
-  static const ok = 200;
-  static const created = 201;
-  static const accepted = 202;
-  static const noContent = 204;
-  static const badRequest = 400;
-  static const notFound = 404;
-  static const methodNotAllowed = 405;
-  static const unacceptable = 406;
-  static const unsupportedMediaType = 415;
-
-  final int value;
-
-  /// True for the requests processed asynchronously.
-  /// @see https://jsonapi.org/recommendations/#asynchronous-processing).
-  bool get isPending => value == accepted;
-
-  /// True for successfully processed requests
-  bool get isSuccessful => value >= ok && value < 300 && !isPending;
-
-  /// True for failed requests (i.e. neither successful nor pending)
-  bool get isFailed => !isSuccessful && !isPending;
-}
-
-Handler loggingMiddleware(Handler handler,
-        {Function(Request request)? onRequest,
-        Function(Response response)? onResponse}) =>
-    (Request request) async {
-      onRequest?.call(request);
-      final response = await handler(request);
-      onResponse?.call(response);
-      return response;
-    };
-
-/// CORS middleware
-Handler corsMiddleware(Handler handler) => (Request request) async {
-      final corsHeaders = {
-        'Access-Control-Allow-Origin': [request.headers.last('origin') ?? '*'],
-        'Access-Control-Expose-Headers': ['Location'],
-      };
-
-      if (request.method == 'options') {
-        const methods = ['POST', 'GET', 'DELETE', 'PATCH', 'OPTIONS'];
-        return Response(
-            204,
-            Body(),
-            Headers.from({
-              ...corsHeaders,
-              'Access-Control-Allow-Methods':
-                  request.headers['Access-Control-Request-Method'] ?? methods,
-              'Access-Control-Allow-Headers':
-                  request.headers['Access-Control-Request-Headers'] ?? ['*'],
-            }));
-      }
-      final response = await handler(request);
-      response.headers.addAll(corsHeaders);
-      return response;
-    };
-
-extension HeaderExt on Headers {
-  String? last(String key) {
-    final v = this[key];
-    return (v != null && v.isNotEmpty) ? v.last : null;
-  }
-}
+export 'package:json_api/src/http/status_code.dart';
diff --git a/lib/server.dart b/lib/server.dart
index 1cf7a97..d090ab0 100644
--- a/lib/server.dart
+++ b/lib/server.dart
@@ -1,13 +1,15 @@
 /// JSON:API server on top of dart:io.
+/// WARNING: This library is in beta stage. The API is subject to change.
 library server;
 
 export 'package:json_api/src/server/controller.dart';
-export 'package:json_api/src/server/controller_router.dart';
+export 'package:json_api/src/server/cors_middleware.dart';
 export 'package:json_api/src/server/error_converter.dart';
 export 'package:json_api/src/server/errors/collection_not_found.dart';
 export 'package:json_api/src/server/errors/method_not_allowed.dart';
 export 'package:json_api/src/server/errors/relationship_not_found.dart';
 export 'package:json_api/src/server/errors/resource_not_found.dart';
 export 'package:json_api/src/server/errors/unmatched_target.dart';
+export 'package:json_api/src/server/request_validator.dart';
 export 'package:json_api/src/server/response.dart';
-export 'package:json_api/src/server/try_catch_middleware.dart';
+export 'package:json_api/src/server/router.dart';
diff --git a/lib/src/client/client.dart b/lib/src/client/client.dart
index c5b1f0f..f3f32cc 100644
--- a/lib/src/client/client.dart
+++ b/lib/src/client/client.dart
@@ -2,7 +2,6 @@ import 'dart:convert';
 
 import 'package:http_interop/extensions.dart';
 import 'package:http_interop/http_interop.dart' as i;
-import 'package:json_api/http.dart';
 import 'package:json_api/src/client/payload_codec.dart';
 import 'package:json_api/src/client/request.dart';
 import 'package:json_api/src/client/response.dart';
@@ -45,9 +44,8 @@ class Client {
   Future<Map?> _decode(i.Response response) async {
     final json = await response.body.decode(utf8);
     if (json.isNotEmpty &&
-        response.headers
-                .last('Content-Type')
-                ?.toLowerCase()
+        response.headers['Content-Type']?.last
+                .toLowerCase()
                 .startsWith(mediaType) ==
             true) {
       return await _codec.decode(json);
diff --git a/lib/src/http/status_code.dart b/lib/src/http/status_code.dart
new file mode 100644
index 0000000..2b70a25
--- /dev/null
+++ b/lib/src/http/status_code.dart
@@ -0,0 +1,21 @@
+extension type StatusCode(int value) {
+  static const ok = 200;
+  static const created = 201;
+  static const accepted = 202;
+  static const noContent = 204;
+  static const badRequest = 400;
+  static const notFound = 404;
+  static const methodNotAllowed = 405;
+  static const unacceptable = 406;
+  static const unsupportedMediaType = 415;
+
+  /// True for the requests processed asynchronously.
+  /// @see https://jsonapi.org/recommendations/#asynchronous-processing).
+  bool get isPending => value == accepted;
+
+  /// True for successfully processed requests
+  bool get isSuccessful => value >= ok && value < 300 && !isPending;
+
+  /// True for failed requests (i.e. neither successful nor pending)
+  bool get isFailed => !isSuccessful && !isPending;
+}
diff --git a/lib/src/server/controller_router.dart b/lib/src/server/controller_router.dart
deleted file mode 100644
index 4171d1f..0000000
--- a/lib/src/server/controller_router.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-import 'package:http_interop/http_interop.dart';
-import 'package:http_parser/http_parser.dart';
-import 'package:json_api/http.dart';
-import 'package:json_api/routing.dart';
-import 'package:json_api/src/media_type.dart';
-import 'package:json_api/src/server/controller.dart';
-import 'package:json_api/src/server/errors/method_not_allowed.dart';
-import 'package:json_api/src/server/errors/unacceptable.dart';
-import 'package:json_api/src/server/errors/unmatched_target.dart';
-import 'package:json_api/src/server/errors/unsupported_media_type.dart';
-
-class ControllerRouter {
-  ControllerRouter(this._controller, this._matchTarget);
-
-  final Controller _controller;
-  final Target? Function(Uri uri) _matchTarget;
-
-  Future<Response> handle(Request request) async {
-    _validate(request);
-    final target = _matchTarget(request.uri);
-    return await switch (target) {
-      RelationshipTarget() => switch (request.method) {
-          'get' => _controller.fetchRelationship(request, target),
-          'post' => _controller.addMany(request, target),
-          'patch' => _controller.replaceRelationship(request, target),
-          'delete' => _controller.deleteMany(request, target),
-          _ => throw MethodNotAllowed(request.method)
-        },
-      RelatedTarget() => switch (request.method) {
-          'get' => _controller.fetchRelated(request, target),
-          _ => throw MethodNotAllowed(request.method)
-        },
-      ResourceTarget() => switch (request.method) {
-          'get' => _controller.fetchResource(request, target),
-          'patch' => _controller.updateResource(request, target),
-          'delete' => _controller.deleteResource(request, target),
-          _ => throw MethodNotAllowed(request.method)
-        },
-      Target() => switch (request.method) {
-          'get' => _controller.fetchCollection(request, target),
-          'post' => _controller.createResource(request, target),
-          _ => throw MethodNotAllowed(request.method)
-        },
-      _ => throw UnmatchedTarget(request.uri)
-    };
-  }
-
-  void _validate(Request request) {
-    final contentType = request.headers.last('Content-Type');
-    if (contentType != null && _isInvalid(MediaType.parse(contentType))) {
-      throw UnsupportedMediaType();
-    }
-    if ((request.headers['Accept'] ?? [])
-        .expand((it) => it.split(','))
-        .map((it) => it.trim())
-        .map(MediaType.parse)
-        .any(_isInvalid)) {
-      throw Unacceptable();
-    }
-  }
-
-  bool _isInvalid(MediaType mt) =>
-      mt.mimeType == mediaType &&
-      mt.parameters.isNotEmpty; // TODO: check for ext and profile
-}
diff --git a/lib/src/server/cors_middleware.dart b/lib/src/server/cors_middleware.dart
new file mode 100644
index 0000000..3c288aa
--- /dev/null
+++ b/lib/src/server/cors_middleware.dart
@@ -0,0 +1,23 @@
+import 'package:http_interop/http_interop.dart';
+
+Handler corsMiddleware(Handler handler) =>
+    (Request request) async => switch (request.method) {
+          'options' => Response(
+              204,
+              Body(),
+              Headers.from({
+                'Access-Control-Allow-Methods':
+                    request.headers['Access-Control-Request-Method'] ??
+                        const ['POST', 'GET', 'DELETE', 'PATCH', 'OPTIONS'],
+                'Access-Control-Allow-Headers':
+                    request.headers['Access-Control-Request-Headers'] ??
+                        const ['*'],
+              })),
+          _ => await handler(request)
+        }
+          ..headers.addAll({
+            'Access-Control-Allow-Origin': [
+              request.headers['origin']?.last ?? '*'
+            ],
+            'Access-Control-Expose-Headers': const ['Location'],
+          });
diff --git a/lib/src/server/error_converter.dart b/lib/src/server/error_converter.dart
index 6300408..95ab1b8 100644
--- a/lib/src/server/error_converter.dart
+++ b/lib/src/server/error_converter.dart
@@ -1,4 +1,5 @@
-import 'package:http_interop/http_interop.dart' as http;
+import 'package:http_interop/http_interop.dart';
+import 'package:http_interop_middleware/http_interop_middleware.dart';
 import 'package:json_api/document.dart';
 import 'package:json_api/src/server/errors/collection_not_found.dart';
 import 'package:json_api/src/server/errors/method_not_allowed.dart';
@@ -9,62 +10,50 @@ import 'package:json_api/src/server/errors/unmatched_target.dart';
 import 'package:json_api/src/server/errors/unsupported_media_type.dart';
 import 'package:json_api/src/server/response.dart';
 
-/// The error converter maps server exceptions to JSON:API responses.
-/// It is designed to be used with the TryCatchHandler from the `json_api:http`
-/// package and provides some meaningful defaults out of the box.
-class ErrorConverter {
-  ErrorConverter({
-    this.onMethodNotAllowed,
-    this.onUnmatchedTarget,
-    this.onCollectionNotFound,
-    this.onResourceNotFound,
-    this.onRelationshipNotFound,
-    this.onError,
-  });
-
-  final Future<http.Response> Function(MethodNotAllowed)? onMethodNotAllowed;
-  final Future<http.Response> Function(UnmatchedTarget)? onUnmatchedTarget;
-  final Future<http.Response> Function(CollectionNotFound)?
-      onCollectionNotFound;
-  final Future<http.Response> Function(ResourceNotFound)? onResourceNotFound;
-  final Future<http.Response> Function(RelationshipNotFound)?
-      onRelationshipNotFound;
-  final Future<http.Response> Function(dynamic, StackTrace)? onError;
-
-  Future<http.Response> call(Object? error, StackTrace trace) async =>
-      switch (error) {
-        MethodNotAllowed() =>
-          await onMethodNotAllowed?.call(error) ?? methodNotAllowed(),
-        UnmatchedTarget() =>
-          await onUnmatchedTarget?.call(error) ?? badRequest(),
-        CollectionNotFound() => await onCollectionNotFound?.call(error) ??
-            notFound(OutboundErrorDocument([
-              ErrorObject(
-                title: 'Collection Not Found',
-                detail: 'Type: ${error.type}',
-              )
-            ])),
-        ResourceNotFound() => await onResourceNotFound?.call(error) ??
-            notFound(OutboundErrorDocument([
-              ErrorObject(
-                title: 'Resource Not Found',
-                detail: 'Type: ${error.type}, id: ${error.id}',
-              )
-            ])),
-        RelationshipNotFound() => await onRelationshipNotFound?.call(error) ??
-            notFound(OutboundErrorDocument([
-              ErrorObject(
-                title: 'Relationship Not Found',
-                detail: 'Type: ${error.type}'
-                    ', id: ${error.id}'
-                    ', relationship: ${error.relationship}',
-              )
-            ])),
-        UnsupportedMediaType() => unsupportedMediaType(),
-        Unacceptable() => unacceptable(),
-        _ => await onError?.call(error, trace) ??
-            response(500,
-                document: OutboundErrorDocument(
-                    [ErrorObject(title: 'Internal Server Error')]))
-      };
-}
+/// Creates a middleware that maps server exceptions to HTTP responses.
+Middleware errorConverter({
+  Future<Response> Function(MethodNotAllowed)? onMethodNotAllowed,
+  Future<Response> Function(UnmatchedTarget)? onUnmatchedTarget,
+  Future<Response> Function(CollectionNotFound)? onCollectionNotFound,
+  Future<Response> Function(ResourceNotFound)? onResourceNotFound,
+  Future<Response> Function(RelationshipNotFound)? onRelationshipNotFound,
+  Future<Response> Function(Object, StackTrace)? onError,
+}) =>
+    middleware(
+        onError: (error, trace, _) async => switch (error) {
+              Response() => error,
+              MethodNotAllowed() =>
+                await onMethodNotAllowed?.call(error) ?? methodNotAllowed(),
+              UnmatchedTarget() =>
+                await onUnmatchedTarget?.call(error) ?? badRequest(),
+              CollectionNotFound() => await onCollectionNotFound?.call(error) ??
+                  notFound(OutboundErrorDocument([
+                    ErrorObject(
+                      title: 'Collection Not Found',
+                      detail: 'Type: ${error.type}',
+                    )
+                  ])),
+              ResourceNotFound() => await onResourceNotFound?.call(error) ??
+                  notFound(OutboundErrorDocument([
+                    ErrorObject(
+                      title: 'Resource Not Found',
+                      detail: 'Type: ${error.type}, id: ${error.id}',
+                    )
+                  ])),
+              RelationshipNotFound() =>
+                await onRelationshipNotFound?.call(error) ??
+                    notFound(OutboundErrorDocument([
+                      ErrorObject(
+                        title: 'Relationship Not Found',
+                        detail: 'Type: ${error.type}'
+                            ', id: ${error.id}'
+                            ', relationship: ${error.relationship}',
+                      )
+                    ])),
+              UnsupportedMediaType() => unsupportedMediaType(),
+              Unacceptable() => unacceptable(),
+              _ => await onError?.call(error, trace) ??
+                  response(500,
+                      document: OutboundErrorDocument(
+                          [ErrorObject(title: 'Internal Server Error')]))
+            });
diff --git a/lib/src/server/request_validator.dart b/lib/src/server/request_validator.dart
new file mode 100644
index 0000000..c4e97d0
--- /dev/null
+++ b/lib/src/server/request_validator.dart
@@ -0,0 +1,25 @@
+import 'package:http_interop/http_interop.dart';
+import 'package:http_interop_middleware/http_interop_middleware.dart';
+import 'package:http_parser/http_parser.dart';
+import 'package:json_api/src/media_type.dart';
+import 'package:json_api/src/server/errors/unacceptable.dart';
+import 'package:json_api/src/server/errors/unsupported_media_type.dart';
+
+final requestValidator = middleware(onRequest: (Request request) async {
+  final contentType = request.headers['Content-Type']?.last;
+  if (contentType != null && _isInvalid(MediaType.parse(contentType))) {
+    throw UnsupportedMediaType();
+  }
+  if ((request.headers['Accept'] ?? [])
+      .expand((it) => it.split(','))
+      .map((it) => it.trim())
+      .map(MediaType.parse)
+      .any(_isInvalid)) {
+    throw Unacceptable();
+  }
+  return null;
+});
+
+bool _isInvalid(MediaType mt) =>
+    mt.mimeType == mediaType &&
+    mt.parameters.isNotEmpty; // TODO: check for ext and profile
diff --git a/lib/src/server/router.dart b/lib/src/server/router.dart
new file mode 100644
index 0000000..8f985e2
--- /dev/null
+++ b/lib/src/server/router.dart
@@ -0,0 +1,32 @@
+import 'package:http_interop/http_interop.dart';
+import 'package:json_api/routing.dart';
+import 'package:json_api/src/server/controller.dart';
+import 'package:json_api/src/server/errors/method_not_allowed.dart';
+import 'package:json_api/src/server/errors/unmatched_target.dart';
+
+Handler router(Controller controller, Target? Function(Uri uri) matchTarget) =>
+    (request) => switch (matchTarget(request.uri)) {
+          RelationshipTarget target => switch (request.method) {
+              'get' => controller.fetchRelationship(request, target),
+              'post' => controller.addMany(request, target),
+              'patch' => controller.replaceRelationship(request, target),
+              'delete' => controller.deleteMany(request, target),
+              _ => throw MethodNotAllowed(request.method)
+            },
+          RelatedTarget target => switch (request.method) {
+              'get' => controller.fetchRelated(request, target),
+              _ => throw MethodNotAllowed(request.method)
+            },
+          ResourceTarget target => switch (request.method) {
+              'get' => controller.fetchResource(request, target),
+              'patch' => controller.updateResource(request, target),
+              'delete' => controller.deleteResource(request, target),
+              _ => throw MethodNotAllowed(request.method)
+            },
+          Target target => switch (request.method) {
+              'get' => controller.fetchCollection(request, target),
+              'post' => controller.createResource(request, target),
+              _ => throw MethodNotAllowed(request.method)
+            },
+          _ => throw UnmatchedTarget(request.uri)
+        };
diff --git a/lib/src/server/try_catch_middleware.dart b/lib/src/server/try_catch_middleware.dart
deleted file mode 100644
index b9cba2b..0000000
--- a/lib/src/server/try_catch_middleware.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:http_interop/http_interop.dart';
-
-/// An [Handler] wrapper which calls the wrapped [handler] and does
-/// the following:
-/// - when an instance of [Response] is returned or thrown by the
-///   wrapped handler, the response is returned
-/// - when another error is thrown by the wrapped handler and
-///   the [onError] callback is set, the error will be converted to a response
-/// - otherwise the error will be rethrown.
-
-Handler tryCatchMiddleware(Handler handler,
-        {Future<Response> Function(dynamic, StackTrace)? onError}) =>
-    (Request request) async {
-      try {
-        return await handler(request);
-      } on Response catch (response) {
-        return response;
-      } catch (error, stacktrace) {
-        return await onError?.call(error, stacktrace) ?? (throw error);
-      }
-    };
diff --git a/pubspec.yaml b/pubspec.yaml
index d378e2d..9d9a8c9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -8,6 +8,7 @@ environment:
 dependencies:
   http_parser: ^4.0.0
   http_interop: ^2.0.0
+  http_interop_middleware: ^0.1.0
 
 dev_dependencies:
   lints: ^4.0.0
diff --git a/test/test_handler.dart b/test/test_handler.dart
index e9177b1..da8ffe7 100644
--- a/test/test_handler.dart
+++ b/test/test_handler.dart
@@ -1,5 +1,5 @@
 import 'package:http_interop/http_interop.dart';
-import 'package:json_api/http.dart';
+import 'package:http_interop_middleware/http_interop_middleware.dart';
 import 'package:json_api/routing.dart';
 import 'package:json_api/server.dart';
 
@@ -9,23 +9,10 @@ import '../example/server/repository_controller.dart';
 Handler testHandler(
         {Iterable<String> types = const ['users', 'posts', 'comments'],
         Function(Request request)? onRequest,
-        Function(Response response)? onResponse,
-        Future<Response> Function(dynamic, StackTrace)? onError}) =>
-    loggingMiddleware(
-        corsMiddleware(tryCatchMiddleware(
-            ControllerRouter(
-                    RepositoryController(
-                        InMemoryRepo(types), () => (_counter++).toString()),
-                    StandardUriDesign.matchTarget)
-                .handle,
-            onError: ErrorConverter(
-                    onError: onError ??
-                        (err, trace) {
-                          print(trace);
-                          throw err;
-                        })
-                .call)),
-        onRequest: onRequest,
-        onResponse: onResponse);
+        Function(Response response)? onResponse}) =>
+    corsMiddleware.add(requestValidator).add(errorConverter()).call(
+        router(RepositoryController(InMemoryRepo(types), _nextId),
+            StandardUriDesign.matchTarget));
 
+String _nextId() => (_counter++).toString();
 int _counter = 0;
diff --git a/test/unit/http/logging_middleware_test.dart b/test/unit/http/logging_middleware_test.dart
deleted file mode 100644
index ca1faaf..0000000
--- a/test/unit/http/logging_middleware_test.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-import 'dart:convert';
-
-import 'package:http_interop/http_interop.dart';
-import 'package:json_api/http.dart';
-import 'package:test/expect.dart';
-import 'package:test/scaffolding.dart';
-
-main() {
-  Response response = Response(200, Body.text('hello', utf8), Headers());
-
-  Future<Response> handler(Request rq) async => response;
-
-  group('Logging Middleware', () {
-    test('Can log', () async {
-      Request? loggedRq;
-      Response? loggedRs;
-
-      final request = Request('get', Uri(host: 'localhost'), Body(), Headers());
-      final response = await loggingMiddleware(handler,
-          onRequest: (r) => loggedRq = r,
-          onResponse: (r) => loggedRs = r)(request);
-      expect(loggedRq, same(request));
-      expect(loggedRs, same(response));
-    });
-  });
-}
diff --git a/test/unit/http/cors_middleware_test.dart b/test/unit/server/cors_middleware_test.dart
similarity index 98%
rename from test/unit/http/cors_middleware_test.dart
rename to test/unit/server/cors_middleware_test.dart
index 6dc2939..761bba8 100644
--- a/test/unit/http/cors_middleware_test.dart
+++ b/test/unit/server/cors_middleware_test.dart
@@ -1,7 +1,7 @@
 import 'dart:convert';
 
 import 'package:http_interop/http_interop.dart';
-import 'package:json_api/http.dart';
+import 'package:json_api/server.dart';
 import 'package:test/expect.dart';
 import 'package:test/scaffolding.dart';
 
diff --git a/test/unit/server/error_converter_test.dart b/test/unit/server/error_converter_test.dart
deleted file mode 100644
index b2fbc4b..0000000
--- a/test/unit/server/error_converter_test.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-import 'dart:convert';
-
-import 'package:http_interop/extensions.dart';
-import 'package:json_api/server.dart';
-import 'package:test/test.dart';
-
-void main() {
-  test('500', () async {
-    final r = await ErrorConverter().call('Foo', StackTrace.current);
-    expect(r.statusCode, equals(500));
-    expect(await r.body.decode(utf8),
-        equals('{"errors":[{"title":"Internal Server Error"}]}'));
-  });
-}
