Generate API client from Django REST framework API - django

I have an website in Django that is using the REST framework to provide an API.
Is there a way to generate an API client that can be used to communicate with this API that provides objects mapping the contents of the API?

If you're talking about a javascript client API, I have a django management task that I use to generate a javascript library from my DRF API
using AngularJS 1.*. I'm still using DRF 2.4, for easy nested object writes, and Django 1.7. Here it is as a github gist
Take that file, stick it in <app>/management/commands/ and call it like:
python manage.py rest_framework_2_js rest_api.gen.js [base_factory_name] [server_base_url]
If your base_factory_name was foo and you had an API object at server_base_url/Bar/ named Bar, you would use it like:
foo.Bar.get(42)
.then(function(bar_inst) {
console.log(bar_inst);
bar_inst.baz = 77;
bar_inst.save()
.then(function() {
console.log('bar_inst has been saved');
});
})
or
foo.BarList.get('filter_a=5&field_filter_b=abc,d')
.then(function(data) {
console.log(data.results);
})
Each instance in the data.result will be a foo.Bar instance.
You can add callbacks before sending to the server and after retrieving from the server using foo.Bar.pre_save(function (inst) {/*callback mutator*/}) and foo.Bar.post_restore( function(inst) { /*callback mutator*/}).
Anyways, this management task is not productized and it has only one user - me, but I have been using it for 2 years and it works great for me :-) We can work to get it working in your configuration if you like. Naturally the biggest caveat is the AngularJS 1.* dependency.

Related

NextJS using Django API - How to choose best pattern

I have GeoDjango running on a digital ocean droplet and I'm rewriting project from VueJs to NextJs hosted on Vercel.
In Vue we have service pattern connected with store that is responsible for fetching and updating data.
I figured out the fetching part which is quite good but I'm still trying to figure out the best way to update data.
How should I construct the CRUD layer without using the NextJs API folder ( I don't want to have another backend calling my Django backend).
Should I use context?
Should I use middleware?
Should I create custom services? How to call them then? Is there an equivalent of store in NextJs?
I'm asking because I want to avoid cluttering as right now I'm using fetch POST on pages. I'm using NextAuth that gives me a context with jwt token.
Thank you for any hints
For Next.js, you can use rewrites to proxy requests to your backend. This way you can access your existing backend from relative URLs just like if they were in your API routes. You can do this explicitly for each route, Or you can use the incremental adoption pattern which will check for an existing route in your Next.js app before proxying the request back to your django server.
// next.config.js
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/api/:path*',
destination: `https://your.django.app/api/:path*`,
},
],
}
},
}

How to consume SOAP webservice in SAP UI5?

I have a SOAP webservice and details of the service provided are: webservice name: "xyz", username: "Ashish", class name: "Initializer" and method name: "Fetchvalue". I have to call the method "Fetchvalue" in which an object of class "Initializer" is used as a paramter. I am developing a web app using SAP UI5, i tried a lot to call this method but not able to get a proper solution for this. Will you please tell me how can i call this method with specific requiremenst resulting in desired output from the webservice.
It would be possible to call a SOAP method from a UI5 application, but there are no specific UI5 components to help you with that. This means that you'll just have to make do with the lower level function, either provided by jQuery or by calling XMLHttpRequest directly.
jQuery has a specific soap plugin for this purpose, that makes calling SOAP methods quite easy:
$.soap({
url: 'http://my.server.com/soapservices/',
method: 'helloWorld',
data: {
name: 'Ashish Jain',
msg: 'Hi!'
},
success: function (soapResponse) {
// do stuff with soapResponse
},
error: function (SOAPResponse) {
// show error
}
});
Please note that the eventual call is made using XMLHttpRequest, which requires CORS headers to be setup on the server hosting your SOAP service. Alternatively, you could setup a proxy on the server that is hosting your UI5 app, that links to the server hosting the SOAP service. If you go this path, you may also want to see if you could have this proxy layer to translate SOAP into JSON for you. That would allow you to easily use a JSONModel from your UI5 app, which makes things easier and cleaner at the UI side.
Since you mentioned that you'll have to call the SOAP service using a username and password, I think a word of caution is mandatory in this answer. UI5 apps run in the browser of your end-user. This means that your end-user can have a look at your Javascript code. Hence, having a username and password in your Javascript code is bad practice. You may want to see if you can push authentication to the SOAP end-point to the proxy if possible.

How to Create Restful Web Services using c++ language and JSON Parser

I am working on Embedded Linux and I want Restful web services to run on my Linux Custom Board.
My objective is to send/receive data (in JSON format) to/from web server (httpd server).
Also, I want to create that Restful Web services using C++ language.
Please see below idea about need of Restful Web Services for my Linux Custom Board.
First, I will send HTTP request with JSON format data through httpd server which is running on my linux board.
Then, I want to create one binary or server which implements this Restful Web Services in c++ language which is used to handle HTTP request.
Then, This C++ binary will send response back to httpd server for display purpose over web browser.
Does anyone have idea or example about how to create Restful Web Services using C++ language?
Any help on Restful is welcome.
Does any one has idea about ffead and its functionalities which fulfills my Restful Web Services or not?
Restbed can address your requirements with the exception of a JSON parser. However, combining a solution with one of the many C++ JSON implementations already available requires very little work.
#include <memory>
#include <string>
#include <cstdlib>
#include <sstream>
#include <jsonbox.h>
#include <restbed>
using namespace std;
using namespace restbed;
void get_method_handler( const shared_ptr< Session > session )
{
const auto request = session->get_request( );
size_t content_length = request->get_header( "Content-Length", 0 );
session->fetch( content_length, [ ]( const shared_ptr< Session >& session, const Bytes& body )
{
JsonBox::Value json;
json.loadFromString( string( body.begin( ), body.end( ) ) );
//perform awesome solutions logic...
stringstream stream;
json.writeToStream( stream );
string response_body = stream.str( );
session->close( OK, response_body, { { "Content-Length", ::to_string( response_body.length( ) }, { "Content-Type": "application/json" } } );
} );
}
int main( const int, const char** )
{
auto resource = make_shared< Resource >( );
resource->set_path( "/resource" );
resource->set_method_handler( "GET", get_method_handler );
auto settings = make_shared< Settings >( );
settings->set_port( 1984 );
settings->set_default_header( "Connection", "close" );
Service service;
service.publish( resource );
service.start( settings );
return EXIT_SUCCESS;
}
Alternative RESTful frameworks
Casablanca C++ REST SDK (edit: project moved & renamed)
CPP-Netlib
RESTful Mapper
Simple REST (edit: no longer exist)
Google is your friend.
Alternative JSON frameworks
LibJSON
RapidJSON
JSONMe
JSON++
JSON-CPP
Google is your friend.
I know this is late, but something new has come up a year or two ago.
If you're into hardcore asynchronous programming for high-performance, you can consider boost::beast. It's a layer above boost::asio (the generic tcp/udp and i/o library) that has both http(s) and websocket servers/clients.
Keep in mind that these are ideal for performance and full freedom in multithreading (you can literally run your server on thousands of threads with almost perfect caching if you have a server that can take it), but they have a steep learning-curve. Do this only if you need to have absolute control over everything!
I'm using oatpp in combination with nlohmann JSON. Though you may get away with purely oatpp as it has built-in JSON handling features. Please, see a step by step guide.
If you are using Apache2 or Nginx as Web server and want to deploy RESTful JSON Web services on it, try ngrest. It's easy in use and fast.
To represent JSON in C++ ngrest uses standard C++ types (generic types, C++ structs, typedefs, STL containers, etc.). Access to raw JSON is possible too. Optionally you can access DBMS using ngrest-db extension.
An example of typical workflow of creating the C++ service:
1) create a service (it may be implemented as h/cpp or single hpp file):
ngrest create -d hpp Users
2) implement data structures and operations (resources). Edit users/users/src/Users.hpp like that:
// a structure to represent data in JSON
struct User {
int id;
std::string name;
std::string email;
};
// *location: /users
class Users: public ngrest::Service
{
public:
// *method: POST
int add(const User& user) {
return Db::inst().users().insert(user).lastInsertId();
}
// *location: /{id}
User get(int id) {
return Db::inst().users().selectOne("id = ?", id);
}
// *method: DELETE
void remove(int id) {
Db::inst().users().deleteWhere("id = ?", id);
}
};
3) run your service for the test:
cd users
ngrest
4) test your RESTful Web service using service tester: http://localhost:9098/ngrest/service/users
5) deploy your Web Service library to the Web Server running ngrest.
If you are building a RESTful service client, you should consider a library such as Casablanca (which is maintained by Microsoft and is a cross-platform solution for accessing RESTful APIs) https://github.com/Microsoft/cpprestsdk.
Otherwise you could also use libcurl https://curl.haxx.se/libcurl
There are C++ bindings for curl. Depending on your board, libcurl might already be installed. All you have to do would be to use the C++ bindings.
Both libraries handle http/https. libcurl does not provide a json parser but you could easily combine it with any C++ json parser available. Casablanca is complete and built on an asynchronous model. It relies however on the Boost libraries. Nevertheless I have used on an Intel Edison board with success.
For send/receive data in JSON format, try jsoncpp
Use an embedded web server, such as Mongoose, CivetWeb or NXWeb. (see this post for more details)
Generally these are trivial to embed in your application, then you only need a JSON library to parse/create JSON data in the web server route handlers. REST is, after all, only HTTP requests so this is easy to implement using one of the above.
Probably your best bet is to use FastCGI to create a module to interface with your web server. This should prevent you from having to implement your own HTTP server.
There are some frameworks like CppCMS that embed their own HTTP server, so you might not need something as heavy as Apache httpd.
I'm assuming your REST service will not be under heavy load.
Also, CppCMS supports JSON out of the box, see http://cppcms.com/wikipp/en/page/cppcms_1x_json.
The minimal web service capable of using SHTML would include Open SSL..
Here is an example of a simple C++ SHTML Server using TCP/IP calls no framework other than OpenSSL
simple C++ SHTML Web Service Server using openssl
simple C++ SHTML Web Service Client using openssl
Here is a pretty comprehensive list of Restful Frameworks by language like 300 of them..
List of Restful Web Service Frameworks
As of writing this answer searching that more comprehensive list for "C++" yields
more than 60 entries.

Am I reinventing the wheel with this ASP.NET Web API based webserver?

In a standalone (selfhosted) application, I would like to have an httpserver that on a single base adress can either serve simple web pages (without any serverside dynamics/scripting, it just returns the content request files) or serve RESTful webservices:
when http://localhost:8070/{filePath} is requested, it should return the content of the file (html, javascript, css, images), just like a normal simple webserver
everything behind http://localhost:8070/api/ should just act as a normal RRESTful Web API
My current approach uses ASP.NET Web API to server both the html pages and the REST APIs:
var config = new HttpSelfHostConfiguration("http://localhost:8070/");
config.Formatters.Add(new WebFormatter());
config.Routes.MapHttpRoute(
name: "Default Web",
routeTemplate: "{fileName}",
defaults: new { controller = "web", fileName = RouteParameter.Optional });
config.Routes.MapHttpRoute(
name: "Default API",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
The WebController is the controller that serves the web pages with this naive code:
public class WebController : ApiController
{
public HttpResponseMessage Get(string fileName = null)
{
/// ...
var filePath = Path.Combine(wwwRoot, fileName);
if (File.Exists(filePath))
{
if (HasCssExtension(filePath))
{
return this.Request.CreateResponse(
HttpStatusCode.OK,
GetFileContent(filePath),
"text/css");
}
if (HasJavaScriptExtension(filePath))
{
return this.Request.CreateResponse(
HttpStatusCode.OK,
GetFileContent(filePath),
"application/javascript");
}
return this.Request.CreateResponse(
HttpStatusCode.OK,
GetFileContent(filePath),
"text/html");
}
return this.Request.CreateResponse(
HttpStatusCode.NotFound,
this.GetFileContnet(Path.Combine(wwwRoot, "404.html")),
"text/html");
}
}
And again, for everything behind /api, controllers for normal REST APIs are used.
My question now is: Am I on the right track? I kind of feel that I am rebuilding a webserver here, reinventing the wheel. And I guess that there are probably a lot of http request web browsers could make that I do not handle correctly here.
But what other option do I have if I want to self host and at the same time server REST web APIs and web pages over the same base address?
Looks like you are trying to recreate asp.net FileHandler for self host. There is a better solution though. Using Katana(an OWIN host) as the hosting layer for web API. OWIN supports hosting multiple OWIN frameworks in the same app. In your case, you can host both web API and a file handler in the same OWIN app.
Filip has a good blog post on this to get you started here. You can use configuration code like this,
public void Configuration(IAppBuilder appBuilder)
{
// configure your web api.
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("default-api", "api/{controller}");
appBuilder.UseWebApi(config);
// configure your static file handler.
appBuilder.UseStaticFiles();
}
IMO there is nothing wrong with what you are doing. I use self-host for delivering files, html docs as well as being a regular API. At the core, self-host is using HTTP.SYS just as IIS is.
As RaghuRam mentioned there are Owin hosts that have some optimizations for serving static files, but WCF selfhost is quite capable of getting decent perf for serving files.
See this link which uses a more straigftforward approach
Setting app a separate Web API project and ASP.NET app
RouteTable.Routes.IgnoreRoute(".js");
RouteTable.Routes.IgnoreRoute(".html");

How do I authenticate and consume an external api with backbone?

I'm trying to create a very basic little backbone app that displays stats from my company's Harvest account. They have a REST API which authenticates via Basic Auth or oAuth. I seem to be faced with two problems here:
Authentication
Cross-origin requests
So I've started with setting the url for my collection to the respective url:
var Projects = Backbone.Collection.extend({
url: 'https://mycompany.harvestapp.com/projects',
});
And I've tried using this basic auth plugin but I can't tell if that part is working because I'm still getting Access-Control-Allow-Origin errors.
What's the best way to go about this?
This other StackOverflow question is similar and has more details that you should take a look at.
But the general idea is this, if you don't have access to the remote server (which I presume you do not with Harvest) then you need to perform the cross-site requests from your own server that you do control, most likely the one you are deploying this backbone app on. That means writing some server-side code (PHP, Node, etc.) to perform the requests (perfectly legal from server side) and then having your client (Backbone app) request from these scripts.
Here is a brief/pseudo-example with php:
request.php
<?php
echo file_get_contents('https://mycompany.harvestapp.com/projects');
?>
projects.js
var Projects = Backbone.Collection.extend({
url: 'request.php',
});