NAME Cookieville - REST API for your database VERSION 0.05 DESCRIPTION Cookieville is a a web application which allow you to inspect and run queries on your SQL database using a REST interface. This distribution also contain Cookieville::Client for easy blocking and non-blocking integration with the server. This application need a DBIx::Class based schema to work. It will query the result files on disk to gather meta information about the schema instead of looking into the running database. THIS SERVER IS CURRENTLY EXPERIMENTAL AND WILL CHANGE WITHOUT ANY NOTICE. SYNOPSIS $ MOJO_CONFIG=/path/to/mojo.conf cookieville daemon --listen http://*:5000 Example "MOJO_CONFIG": $ cat /path/to/mojo.conf { # config for cookieville inactive_timeout => 10, schema_class => "My::Schema", connect_args => { "DBI:mysql:database=some_database;host=localhost", "dr_who", "MostS3cretpassWord", }, # config for hypnotoad - https://metacpan.org/pod/Mojo::Server::Hypnotoad hypnotoad => { listen => [ "http://*:5000" ], workers => 10, }, # will set up logging to a given file log => { path => "/path/to/cookieville.log", level => "info", # or debug }, } TIP: Give config file the file mode 0600 to protect your connect passwords. TIP: Run Cookieville with hypnotoad and enough workers in production. Reason for this is that DBIx::Class is blocking, and therefor can only handle one database opartion pr. worker. You might also want to tweak "inactive_timeout" to prevent a worker from running a query for too long. RESOURCES * GET / Returns a description of this application: { "version": "0.01", "source": "https://github.com/jhthorsen/cookieville", "resources": { "schema_source_list": [ "GET", "/sources" ], "schema_for_source": [ "GET", "/:source/schema" ], "source_search": [ "GET", "/:source/search?q=:json&limit=:int&order_by:json" ], "source_delete": [ "DELETE", "/:source/:id" ], "source_patch": [ "PATCH", "/:source/:id" ], "source_update_or_insert": [ "PUT", "/:source" ] } } The environment variable "COOKIEVILLE_INFO" can be used to limit the data returned: COOKIEVILLE_INFO=source,resources * GET /sources Returns a list of available sources (resultsets). Example: [ "Users", "Posts" ] * GET /:source/schema Returns the schema for the given "source". * GET /:source/search Does a SELECT from the given "source" with a given set of query params: * q=:json (mandatory) "q" will be deserialized and used as the query part. * columns=:json (optional) Only output the given columns. Example: columns=["id","name"] * limit=:int (optional) Used to limit the number of rows in the output. * page=:int (optional) Used for pagination when "limit" is specified. * order_by=:json (optional) Sort the result by column(s). Examples: order_by={"-desc","name"} order_by=["name","id"] The return value will be a JSON document containing the rows. Example: { data: [ { "id": 1002, "name": "Jan Henning Thorsen", "age": 31 }, { "id": 3005, "name": "Billy West", "age": 62 } ] } TODO: Make sure integers from the database are actual integers in the result JSON. The format .csv is also supported. Example: GET /Users.csv?q={"age":31}&order_by=name * DELETE /:source/:id Used to DELETE a single record identified by "id". The return value will be a JSON document with the number of rows deleted: {"n":1} NOTE: This will be "{"n":0}" if the record was already deleted. * PATCH /:source/:id Used to do a (partial) UPDATE of a single row identified by "id". The HTTP body must be a JSON structure with the data to update to. The return value will have the new document. Example: { "data": { "id": 1002, "name": "Jan Henning Thorsen", "age": 31 } } Will return 404 if the given "id" does not match any records in the database. * PUT /:source Used to INSERT or UPDATE a single row. The HTTP body must be a JSON structure with the data to insert or update. The return value will be a JSON document containing all the data for the inserted or updated row. Example: { "inserted": true, # or false "data": { "id": 1002, "name": "Jan Henning Thorsen", "age": 31 } } Error handling The API will return "200 OK" on success and another error code on failure: * 400 Return the document below on invalid input data. "message" holds a description of what is missing. Example: { "message": "Missing (q) query param." } * 401 Return the document below on when not authorized. "message" holds a description of why not. Example: { "message": "Invalid token." } * 404 Return the document below if the given resource could not be found. "message" holds a description of what is not found. Examples: { "message": "Resource not found" } { "message": "No source by that name." } { "message": "No matching records in database." } * 500 { "message": "Internal server error." } Generic error when something awful happens. "message" might not make any sense. Look at the server log for more details. Other error codes might be added in future releases. Queries The queries (referred to as the "q" query param in the API) are passed on as the first argument to "search" in DBIx::Class. ATTRIBUTES inactive_timeout $int = $self->inactive_timeout; Used to set the number of seconds before a query agains the database time out. Defaults to value from config, the environment variable "COOKIEVILLE_INACTIVE_TIMEOUT" or 10 seconds. connect_args $array_ref = $self->connect_args; Looks in config to find connection arguments for "schema_class". See "SYNOPSIS" for details. schema_class $class_name = $self->schema_class; Looks in config to find the schema class to use. See "SYNOPSIS" for details. HELPERS db $obj = $self->db; Returns an instance of "schema_class". METHODS setup_routes Used to setup the "RESOURCES". startup Will set up "RESOURCES" and add "HELPERS". COPYRIGHT AND LICENSE Copyright (C) 2014, Jan Henning Thorsen This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. AUTHOR Jan Henning Thorsen - "jhthorsen@cpan.org"