Re: [cgiapp] CGI::Application status update from the maintainer
On Sep 15, 2012, at 10:58 AM, Mark Stosberg wrote: Most web clients support JSON now, which allows for more complex structures than the simple key/value pair that CGI.pm uses. Mark, I think this is relevant to what I'm advocating here. That JSON support is accomplished with javascript parsing a string of JSON data that is stored in the localStorage key/value format. I think that's a very clever use of the localStorage feature because it extends the functionality without adding complexity. Here's an interesting article on that: https://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/ That article points out the value of the simplicity in having the localStorage function and the key/value format, and also how the IndexedDB feature is not so simple. So, I'm not at all alone in seeing the benefits of these simple to use functions and this format. That simplicity is really quite ingenious, and I think this is what's important to keep in mind. What developers are doing with localStorage and JSON on the client side is really not any different in concept than storing a string of JSON data with CGI.pm's save function on the server side. I think that sounds pretty handy. Here's a quote from the author about that: This local storage solution has a few very tempting features for web developers: • It is dead simple • It uses strings for storage instead of complex databases (and you can store more complex data using JSON encoding) ... In that article the author, Chris Heilmann, also discusses how unforeseen uses of the localStorage feature have revealed issues with how it is implemented. He offers several ideas on how to deal with those issues and he concludes his findings with We need to fix this. It seems to me that we are in a somewhat similar situation, but are leaning towards a We need to ditch this conclusion. As I've said, my reasons for advocating for this feature are selfish. I am not qualified to help implement it so how can they be anything but selfish? But, that does not mean others will not also benefit. I think the example of creative and clever usage discussed above helps to demonstrate that. While I may not be able to help implement the feature, I might be able to help with example code and documentation, and I'd be more than willing to try. Kindest Regards, Bill # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On Tue, Sep 18, 2012 at 12:19:46PM -0500, Bill Stephenson wrote: On Sep 15, 2012, at 10:58 AM, Mark Stosberg wrote: Most web clients support JSON now, which allows for more complex structures than the simple key/value pair that CGI.pm uses. Mark, I think this is relevant to what I'm advocating here. That JSON support is accomplished with javascript parsing a string of JSON data that is stored in the localStorage key/value format. I think that's a very clever use of the localStorage feature because it extends the functionality without adding complexity. Here's an interesting article on that: https://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/ That article points out the value of the simplicity in having the localStorage function and the key/value format, and also how the IndexedDB feature is not so simple. So, I'm not at all alone in seeing the benefits of these simple to use functions and this format. That simplicity is really quite ingenious, and I think this is what's important to keep in mind. What developers are doing with localStorage and JSON on the client side is really not any different in concept than storing a string of JSON data with CGI.pm's save function on the server side. I think that sounds pretty handy. Here's a quote from the author about that: This local storage solution has a few very tempting features for web developers: ? It is dead simple ? It uses strings for storage instead of complex databases (and you can store more complex data using JSON encoding) ... In that article the author, Chris Heilmann, also discusses how unforeseen uses of the localStorage feature have revealed issues with how it is implemented. He offers several ideas on how to deal with those issues and he concludes his findings with We need to fix this. It seems to me that we are in a somewhat similar situation, but are leaning towards a We need to ditch this conclusion. As I've said, my reasons for advocating for this feature are selfish. I am not qualified to help implement it so how can they be anything but selfish? But, that does not mean others will not also benefit. I think the example of creative and clever usage discussed above helps to demonstrate that. While I may not be able to help implement the feature, I might be able to help with example code and documentation, and I'd be more than willing to try. Kindest Regards, It is unclear to me exactly what feature you're advocating, even though I went back and read the previous threads. I'd like to point out that while it doesn't matter what the client or the server do, the defacto standard is to send key/value pairs to the server no matter what the HTTP method is. CGI.pm will happly parse a k/v string sent via POST just as it would sent via GET; however, if you send just JSON to the server, you must manually parse whatever is in the POSTDATA field. That's my experience anyway. It'd be nice to have something on the server that recognized the JSON as natively as a k/v query string, particularly for non-GET methods. Also, YUI 3 has some interesting local storage options. Brett Bill # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## #### -- Register Now for cPanel Conference Oct 8-10, 2012, Houston, Texas http://conference.cpanel.net/ # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On 09/15/2012 05:00 PM, Jiří Pavlovský wrote: On 15.9.2012 3:22, Mark Stosberg wrote: Regarding performance, I recently benchmarked accessor generation time for Moo vs Mouse vs Moose vs manual accessors (what CGI::App uses) and raw hashes. In a persistent environment like you are using Moose was generating 162,999 accessers *per second* on my laptop. I suspect that wouldn't be your botteneck. :) This was only marginally slower than the manual accessors benchmark, which would be close to CGI::Application, delivering 187,617 accessors per second. https://raw.github.com/gist/3431863/bf6ecdbe23ea8f97a316b2f4ac1fa211cf48ce86/gistfile1.pl Thanks for the benchmark. Help me understand the results. Is it really so that Moose is on par with the manual accessors while Mouse is an order of magnitude faster? And Moo order of magnitude slower? I'm using Moose a lot, but now I'll have a look at Mouse for sure. That's my reading of it. The source code is is there if you want to check the details of what's going on. Of course, the benchmark doesn't simulate a full application. Within a complete real-world application, it's not clear to me how much accessor speed would matter compared to other factors. Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Bill-- I've sort of taken my own path to create web apps, and while it works for me, I've gotten some blowback for it a few times over the years, but I really don't mind that, so I'll explain it. I have a small demo Note Pad app at www.raspberryperl.com: app - http://raspberryperl.com/cgi-bin/NoteApp/notes.cgi code - http://raspberryperl.com/NoteAppCode/ I stated to look at the code, but I didn't get very far until I ran into this notice: # Do not read, copy, distribute, execute, run, or use # this code without express written permission from # William H. Stephenson. At that point, I was compelled to immediately close the file and stop reading. When a user creates a note I save the data in a file: open(my $NOTE, $note_path/$notepad_number) or Note_home(Error 3: That didn't work); $cgi-save($NOTE); close $NOTE; I see. I hope that $note_path and $notepad_number are handled appropriately, so that a user can't end up overwritting unintended file son our file system. When they want to view or edit a note I load the data into a CGI object: $NOTE = new CGI($FILE); # Throw out the old $NOTE, replace it with a new one close $FILE; return ($NOTE); Using a representation of an HTTP response as a data storage and retrieval system makes me shudder. Someone here has already suggested using XML instead. A format like XML or JSON would offer some greater flexibility. I would also suggest considering a DBI backend, such as DBD::CSV, DBD::AnyData or DBD::SQLite2. This way, your code is a good position to scale up to using a full SQL database if that's ever desired, and you have a standard set up tools and techniques to use between large projects that use SQL and your smaller projects too. I've done a lot of small projects with CGI::Application, and I set a fairly low bar before I start to involve a SQL database. Even on low-cost shared hosting accounts, SQL databases are readily available. And use HTML:Template to display it: $template-param(note_subject = $cgi-param('note_subject')); HTML::Template has a feature called 'associate' which makes this kind of pass-through easier: https://metacpan.org/module/HTML::Template#Miscellaneous-Options I generally use the epoch time of creation to name the file. This gives me an easy way to search by date for documents. 1344045036.txt Or perhaps assign a document number: 0001.txt Either scheme might work well, until you have a lot of documents and need to search by some other key, requiring opening *every* file to check something. In that case, if you know the document number, finding and loading the data is incredibly fast because you're using the system's b-tree to locate it. The trick (if it can be called that) is creating a unique directory for each user so the app knows where to find their documents. Put each different document type in a unique sub-directory and you've really narrowed down where to find what you're looking for. Now, my logic for this being practical is that for the most part database engines were designed to solve just a few problems: 1. Slow processors took a long time ripping through a bunch of files while searching for a specific piece of data. 2. RAM was expensive and a lack of enough RAM made managing large numbers of files impractical and limited what an OS could support. 3. Hard Drive space was expensive, so storing a bunch of files was also expensive. But now, RAM and ROM is comparatively cheap, and processors and OSs are way faster than they were 15 years ago, so this approach keeps becoming more practical for some applications. In my case, the users of the apps I build will never create hundreds of thousands of files. Ten thousand would be the upper ends of what they'd ever create, so this actually works pretty good, and it's very simple to build and maintain. I thought the beauty of SQL was that you expressed *what you wanted*, not *how to make it happen*. I much prefer that to code that open and closes files, scans content line by line, and greps for values. But I agree with the overall sentiment that the best tools for complex projects are often not the same as the best tools for small projects. I use a flexible interpretation of a MVC design approach in my apps, and it would seem to me that if there were ever a necessity to move to a SQL database it should be fairly easy to change the routines to get and put data, and to load the existing data into the database. If that's the case, then my approach might be useful for RAD (rapid application development) if nothing else. It sounds like you've thought about how you might scale up if you needed to. For my own sake, what I am trying to do is limit complexity. Not at all costs, but I do set a high bar for the returns. Complexity, in my opinion and experience, gets expensive fast. I think it's fair to point out that a SQL
Re: [cgiapp] CGI::Application status update from the maintainer
I know that you're right according to common practice, so I have to admit it made me laugh reading that this morning for that very reason. But... in my (weak) defense, in chapter three, page 119, of Lincoln's book, The official guide to programming with CGI.pm is the Advanced Trick that explains Saving State to Files, and that's all I'm really doing here, and nothing more, so I think it's not really accurate to say that how I'm using CGI.pm was never envisioned or intended, or if that's truly the case, I've already explained why it may work now when it may not have when the book was written. As software ages, some features lose favor. We end up with books like Perl Best Practices which advise completely ignoring some features, of Perl and JavaScript: The Good Parts, which does the same for JavaScript. There may have been a time when it was considered a good practice to use CGI.pm for data persistence. It is no longer the case. If we look at web apps designed to run on mobile devices, that are by design pretty simple and tightly focused, than this simple and basic approach to handling data might be a very valuable option. Both Android and iOS have official SQLite support and APIs. Android's demo application for using SQLite is a Notepad. http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html The data format CGI.pm uses is already supported by most web clients, so a way to take advantage of that compatibility make sense to me. Most web clients support JSON now, which allows for more complex structures than the simple key/value pair that CGI.pm uses. These are a few of the things I ponder when I think about and explore frameworks. Thank you for your thoughts. Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On Sep 15, 2012, at 10:41 AM, Mark Stosberg wrote: I stated to look at the code, but I didn't get very far until I ran into this notice: # Do not read, copy, distribute, execute, run, or use # this code without express written permission from # William H. Stephenson. At that point, I was compelled to immediately close the file and stop reading. I apologize, that's in a template I set up years ago in BBEdit, I'll remove it. I'll point out that since I put the link to the code there and invite you to use it, that is permission, still, I'll remove it as it really was an oversight. (Actually, it's a joke. It invokes a chuckle in me because it is so ridicules knowing I'm the only one that ever reads and executes my code and most wouldn't want it anyway and I wouldn't lose anything if they took it. You must have thought that too, didn't it make you chuckle just a little bit?) I see. I hope that $note_path and $notepad_number are handled appropriately, so that a user can't end up overwritting unintended file son our file system. They are hard coded in a set-up file. Using a representation of an HTTP response as a data storage and retrieval system makes me shudder. Shudder? ( :D ) Why? How do you actually avoid that? I understand that in a publicly shared space you have to filter that input, so that's what you do, as best as you can. But do other modules process that same input differently somehow? Does CGI.pm handle it poorly and in a manner that cannot be addressed? You have to use that same data no matter what, so what makes you shudder? HTML::Template has a feature called 'associate' which makes this kind of pass-through easier: Well now, that's just magic! Thanks for pointing that out, I'll give it a spin this evening. And thanks again for listening. I know you're busy... Bill # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Bill, This is fascinating, but I think you're abusing CGI.pm for something it was never intended for. How about using XML::Simple to encode the data and write that into the flat files? # Grab a hashref of data from the posted form my $data = $cgi-Vars; # Dump data into file XMLout($data, OutputFile = $filename); ... # read data from file my $data = XMLin($filename); # use HTML::Template to display it $template-param(%$data); etc On 12 September 2012 19:16, Bill Stephenson bi...@ezinvoice.com wrote: There not yet specific plans for how CGI.pm will be replaced. How do you use the save/restore feature? Thank you, Mark. I appreciate your taking my concerns under consideration. I've sort of taken my own path to create web apps, and while it works for me, I've gotten some blowback for it a few times over the years, but I really don't mind that, so I'll explain it. I have a small demo Note Pad app at www.raspberryperl.com: app - http://raspberryperl.com/cgi-bin/NoteApp/notes.cgi code - http://raspberryperl.com/NoteAppCode/ When a user creates a note I save the data in a file: open(my $NOTE, $note_path/$notepad_number) or Note_home(Error 3: That didn't work); $cgi-save($NOTE); close $NOTE; When they want to view or edit a note I load the data into a CGI object: $NOTE = new CGI($FILE); # Throw out the old $NOTE, replace it with a new one close $FILE; return ($NOTE); And use HTML:Template to display it: $template-param(note_subject = $cgi-param('note_subject')); I generally use the epoch time of creation to name the file. This gives me an easy way to search by date for documents. 1344045036.txt Or perhaps assign a document number: 0001.txt In that case, if you know the document number, finding and loading the data is incredibly fast because you're using the system's b-tree to locate it. The trick (if it can be called that) is creating a unique directory for each user so the app knows where to find their documents. Put each different document type in a unique sub-directory and you've really narrowed down where to find what you're looking for. Now, my logic for this being practical is that for the most part database engines were designed to solve just a few problems: 1. Slow processors took a long time ripping through a bunch of files while searching for a specific piece of data. 2. RAM was expensive and a lack of enough RAM made managing large numbers of files impractical and limited what an OS could support. 3. Hard Drive space was expensive, so storing a bunch of files was also expensive. But now, RAM and ROM is comparatively cheap, and processors and OSs are way faster than they were 15 years ago, so this approach keeps becoming more practical for some applications. In my case, the users of the apps I build will never create hundreds of thousands of files. Ten thousand would be the upper ends of what they'd ever create, so this actually works pretty good, and it's very simple to build and maintain. I've done tests on ripping through 5000 files (with an app like the demo linked above) to find a unique string in one or more files and the result times are not that bad. I suspect they'd be faster if I used ModPerl or FastCGI, but I deploy on a VPS so that's not been an option. My tests resulted in the initial search being a bit slow, but a second search is pretty fast, so I suspect Apache is cacheing some data but I really don't know much about how that works. I have some apps with several thousand users, and some with over 100,000 files in the system. They all run on a VPS and they're pretty darn fast, so again, I'm not finding a compelling reason to move to a SQL database engine. I use a flexible interpretation of a MVC design approach in my apps, and it would seem to me that if there were ever a necessity to move to a SQL database it should be fairly easy to change the routines to get and put data, and to load the existing data into the database. If that's the case, then my approach might be useful for RAD (rapid application development) if nothing else. For my own sake, what I am trying to do is limit complexity. Not at all costs, but I do set a high bar for the returns. Complexity, in my opinion and experience, gets expensive fast. I think it's fair to point out that a SQL database engine may offer another point of entry for hackers to create mayhem. I'm not saying that my approach is more secure, but it seems to me that you must constantly be staying on top of issues specific to any database engine you're using, and that may create additional expense which may be unnecessary. I understand that if you must have a Relational database my approach may not work, but again, with the apps I've created I've not come across that need. So I believe there are some good reasons
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Bill, This is fascinating, but I think you're abusing CGI.pm for something it was never intended for. *** Which is one of the glories of open source. Things keep getting used for stuff that the original writers never envisioned. - Jerry Kaidor # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On Sep 13, 2012, at 12:02 PM, Jerry Kaidor wrote: Hi Bill, This is fascinating, but I think you're abusing CGI.pm for something it was never intended for. *** Which is one of the glories of open source. Things keep getting used for stuff that the original writers never envisioned. I know that you're right according to common practice, so I have to admit it made me laugh reading that this morning for that very reason. But... in my (weak) defense, in chapter three, page 119, of Lincoln's book, The official guide to programming with CGI.pm is the Advanced Trick that explains Saving State to Files, and that's all I'm really doing here, and nothing more, so I think it's not really accurate to say that how I'm using CGI.pm was never envisioned or intended, or if that's truly the case, I've already explained why it may work now when it may not have when the book was written. I'd like to offer a few more things to consider... The OS's native file system is really a database too, and a pretty powerful one, so it seems logical to me that before you start looking to add another layer on top of the OS to manage data you should ask if you have a good reason. I think it's fair to say that this is a question that most frameworks forget to ask when they build their foundation. They assume you're going to want and need a SQL database. I think an option to use a very simple data format is a worthy one. I think that out of the box, a framework should provide a means to do what I did with that demo. I should not have to use SQL to create an app. (of course, that's entirely selfish, and I don't expect anyone to feel at all compelled to accommodate that.) If we look at web apps designed to run on mobile devices, that are by design pretty simple and tightly focused, than this simple and basic approach to handling data might be a very valuable option. The data format CGI.pm uses is already supported by most web clients, so a way to take advantage of that compatibility make sense to me. If we consider that we're now at a point where we can include a computer with the software we create (as opposed to the other way around that it's always been) then using the native OS file system offers opportunities that we shouldn't overlook. Your software owns that entire file system now, it's the only thing that will be using it. The big buzz right now is all about cloud computing, but web app builders have been doing that for a long time now and we know the downsides. The future, as far as I can see forward, looks to me like one where users can have a computer dedicated on site that runs the same app as one they have on a cloud (our web apps) and the user can choose where their data resides, on site, on a cloud, or a combination of both. It has to go this way because we all know that clouds can burst and computers that will run our web apps are getting incredibly cheap and small, so using them both together is the future (well, according to me anyway ) If that's where we're going than we need something to make it easy for the end user to customize their own software. Something so simple that most anyone can do it, or hire someone to do it. This also provides a market for software we make because if our software is simple enough for the end user to modify they have good reason to buy it. Complexity from the start shoots that model in both feet, but as an option it extends the value greatly. These are a few of the things I ponder when I think about and explore frameworks. # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
There not yet specific plans for how CGI.pm will be replaced. How do you use the save/restore feature? Thank you, Mark. I appreciate your taking my concerns under consideration. I've sort of taken my own path to create web apps, and while it works for me, I've gotten some blowback for it a few times over the years, but I really don't mind that, so I'll explain it. I have a small demo Note Pad app at www.raspberryperl.com: app - http://raspberryperl.com/cgi-bin/NoteApp/notes.cgi code - http://raspberryperl.com/NoteAppCode/ When a user creates a note I save the data in a file: open(my $NOTE, $note_path/$notepad_number) or Note_home(Error 3: That didn't work); $cgi-save($NOTE); close $NOTE; When they want to view or edit a note I load the data into a CGI object: $NOTE = new CGI($FILE); # Throw out the old $NOTE, replace it with a new one close $FILE; return ($NOTE); And use HTML:Template to display it: $template-param(note_subject = $cgi-param('note_subject')); I generally use the epoch time of creation to name the file. This gives me an easy way to search by date for documents. 1344045036.txt Or perhaps assign a document number: 0001.txt In that case, if you know the document number, finding and loading the data is incredibly fast because you're using the system's b-tree to locate it. The trick (if it can be called that) is creating a unique directory for each user so the app knows where to find their documents. Put each different document type in a unique sub-directory and you've really narrowed down where to find what you're looking for. Now, my logic for this being practical is that for the most part database engines were designed to solve just a few problems: 1. Slow processors took a long time ripping through a bunch of files while searching for a specific piece of data. 2. RAM was expensive and a lack of enough RAM made managing large numbers of files impractical and limited what an OS could support. 3. Hard Drive space was expensive, so storing a bunch of files was also expensive. But now, RAM and ROM is comparatively cheap, and processors and OSs are way faster than they were 15 years ago, so this approach keeps becoming more practical for some applications. In my case, the users of the apps I build will never create hundreds of thousands of files. Ten thousand would be the upper ends of what they'd ever create, so this actually works pretty good, and it's very simple to build and maintain. I've done tests on ripping through 5000 files (with an app like the demo linked above) to find a unique string in one or more files and the result times are not that bad. I suspect they'd be faster if I used ModPerl or FastCGI, but I deploy on a VPS so that's not been an option. My tests resulted in the initial search being a bit slow, but a second search is pretty fast, so I suspect Apache is cacheing some data but I really don't know much about how that works. I have some apps with several thousand users, and some with over 100,000 files in the system. They all run on a VPS and they're pretty darn fast, so again, I'm not finding a compelling reason to move to a SQL database engine. I use a flexible interpretation of a MVC design approach in my apps, and it would seem to me that if there were ever a necessity to move to a SQL database it should be fairly easy to change the routines to get and put data, and to load the existing data into the database. If that's the case, then my approach might be useful for RAD (rapid application development) if nothing else. For my own sake, what I am trying to do is limit complexity. Not at all costs, but I do set a high bar for the returns. Complexity, in my opinion and experience, gets expensive fast. I think it's fair to point out that a SQL database engine may offer another point of entry for hackers to create mayhem. I'm not saying that my approach is more secure, but it seems to me that you must constantly be staying on top of issues specific to any database engine you're using, and that may create additional expense which may be unnecessary. I understand that if you must have a Relational database my approach may not work, but again, with the apps I've created I've not come across that need. So I believe there are some good reasons to have a simple way, like that in CGI.pm and CGI:Session to store and load data using files. Kindest Regards, Bill Stephenson # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/
Re: [cgiapp] CGI::Application status update from the maintainer
Thank you, Mark. I accept what you so at face value and will seek to educate myself more. Below I address the questions you asked me. On Sat, Sep 08, 2012 at 06:10:55PM -0400, Mark Stosberg wrote: snip.. It would be really nice to merge in some bare bones Authentication and Authorization support - maybe ever by more fully developing CAP's lifecycle. More detailed suggestions would be welcome here, but I'm hestitent. Are there examples of other frames that do something here in a way that's appealing? Not that I know of; I must admit I am a one trick pony wrt frameworks. CAP is all I use and know. I would generally plan to keep the core small, but would welcome more full-featured stacks to be shipped that were based on it, as Titanium did for CGI::Application. My motivation for this is based on our needs. We use CAP to write not just authenticated applications, but those with role based authorization. I have had moderate success using Authen and Authz, but in order to do what was necessary to Authen before Authz or to properly scale out the RBAC restrictions, I had to ditch both and implement my own callbacks during the prerun stage. I suppose both plugins got be over the learning curve, and after I was able to implement authentication and authorization without the plugins. Anyway, my main reason for recommending these 2 in particular as bona fide life cycle events is that the mirror Apache's life cycle. I think this reflects the value of these two stages. The first (authentication) is simply for verifying to some degree that the actor on the system is who they claim to be; the authorization is to ensure that this authentication actor has authorized to execute the targeted run mode. Both are prerun type of stages, but first classing them would be nice. I am not sure I can persuade you to formalize these two stages in particular, but I hope that you consider this. I believe that authentication and RBAC style authorization is only going to become more important, and if nothing these stages would provide a clue to application programmers that CAP is very much suitable for industrial strenght web applications. One project that strikes me as interesting here is Abilities. It addresses the problem space by using a role. It is framework independent, but is intended to be used as part of web applications. https://metacpan.org/module/Abilities Thank you. This is an example of the kind of code I would like to make more easily available to CGI::App based projects. I am a recent addition to this community, and prefer CAP well over the other alternatives. That's good to hear, and welcome. Could you say more about why you prefer it and how you use it? I prefer it because it provided me with a significant epiphany after doing CGI the hard way for too long. It's also more or less what we standardize on internally at cPanel. We use it to write internal applications and external facing APIs that require both authentication and authorization. One of our primary requirements is also raw speed, so even .05 seconds matters to us. This is the basis for my distaste for any sort of MOP layer. However, I concede that in a persistent environment, start up times are amortized over the long term and in this way any cost eventually goes to 0. 1. scalability - it is unnecessarily awkward to have more than 2 levels of subclassing currently. Direct subclass of CAP uses cgi_init; child of subclass uses setup; anything else must call SUPER::setup. Another option I use sometimes is to use the callback system: # Register an action to happen at the init stage. __PACKAGE__-add_callback('init', sub { }); Nice. Note that the Moose API also helps here as well, as it allows you to say this: # Add some additional functionality after 'setup' runs in the parent after 'setup' = sub { my $self = shift; }; Thank you. Yeah, that syntax makes me cring actually :). However, this out of the box seems to provide the basis for a very well structured plugin system. https://metacpan.org/module/Moose::Manual::MethodModifiers#BEFORE-and-AFTER-modifiers The Moose API also provides BUILD, which like our callback system is called for every class in the inheritance hierarchy. So another way to add some initialization functionality would be to put this in your Moose/Mouse based child class: # Another way to add extra functionality when setting up classes. sub BUILD { my $self = shift; } 2. a more fully developed lifecycle model - similar to the one that Apache itself uses. In particular, it would be really helpful to have explicit phases for state (e.g., Session munging), authentication, and authorization. I imagine those 3 in particular to be extremely helpful for building things like role based access control or single sign-on into your application. I agree that
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Brett On 11/09/12 00:05, B. Estrade wrote: I think what I was thinking of for a more developed plugin system is to provide a way to better manage when plugins are fired wrt hooks. For example, have an after or before type of modifier when registering a callback would be nice. Even better would be a way to easily manage the handler queue associated with each hook. It's not entirely clear to me how to ensure that handlerA will fire before handlerB; I also know from reading the documentation that a class level handler will fire before instance level handlers. This might be by design or just a consequence of the implementation; however being able to control the handler execution order would be useful I believe. I don't mind if you choose to continue with CGI::Application rather than switch to CGI::Snapp, but you should be aware that in the latter's documentation, I went to great lengths to spell out this matter. See/Read for yourself my explanation: https://metacpan.org/module/CGI::Snapp#The-Flow-of-Control HTH. -- Ron Savage http://savage.net.au/ Ph: 0421 920 622 # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Bill, Thanks for feedback. Responses are below. On 09/02/2012 01:46 PM, Bill Stephenson wrote: Hi Mark, Nice to hear you're going to move forward with the CAP project. After reading your comments about CGI.pm, and comments from others here, I'm left wondering about a few things. If you're ditching CGI.pm altogether I know that I'll have to as well. That's not going to be easy for me. I love the simplicity of these features: $cgi = new CGI; print $cgi-param('contact_name'); $cgi-save($FILE); $cgi = new CGI($FILE); What will happen to them? The simple name=value data format used by the save routine is the same as the client side data storage in HTML5 (sessionStorage), and I like that it's easy to understand and read this format, and that I can use it on both ends (client/server) of my apps. There not yet specific plans for how CGI.pm will be replaced. How do you use the save/restore feature? I can say that the PSGI environment does seem a good deal cleaner for dealing with input. In CGI, the input by default comes from STDIN (but large content like post requests), and several environment variables. This makes the process a bit mysterious, as well as being action-at-distance a source for confusion. For example, if something has read and consumed STDIN, it may not there again for something else to read. With PSGI, the input is explicitly provided through a Perl hashref, and the body content comes through a standard file handle. While I haven't seen a implementation save/restore for PSGI request objects, it strikes me that it would be pleasant to build. What will happen to CGI::Session? These are all simple, and easy, and familiar. Will the new project have these, or something similar? Like CGI.pm, it will continue to exist, but over time I expect I will quit using it myself and move on to something else. Plack::Middleware::Session is an obvious choice to consider for this. I expect I will personally want to use the Pure SQL approach to session storage, so I will need to first write my own storage driver for it. I will appreciate moving away from something based on CGI.pm, towards using another tool that is shared with other frameworks. http://search.cpan.org/~miyagawa/Plack-Middleware-Session-0.15/lib/Plack/Middleware/Session.pm https://metacpan.org/module/CGI::Session::Driver::pure_sql Those who wish to remain with CGI::App / CGI.pm / CGI::Session are welcome to do so, but will become responsible for more or all of the maintenance of them. As far as I know, Catalyst, Dancer, and Mojolicious do not have the save and new from file routines, they use SQL and a third party database engine only. I know this is probably not something that most developers would miss, but I think it's pretty handy. I also think that it's a good place for beginners to start learning to use a framework. One can go a long way creating apps before they need an SQL database, and becoming proficient with SQL is expensive. For the apps I build it's like swatting a fly with a bulldozer. I'm personally a big fan of SQL and think the related investment is well worth it. I find the basics rather comprehenable: INSERT INTO table VALUES, \%values; UPDATE table SET,\%values; DELETE FROM table WHERE id = ,\$id; SELECT * FROM table WHERE id = ,\$id; ( The above syntax works with DBIx::Simple + SQL::Interp, my preferred access method. ) However, Plack::Middleware::Session does support a file-storage backend: https://metacpan.org/module/Plack::Session::Store::File Anyway, I also want to thank you for all you've done with CGI.pm and other modules I use everyday. I, like so many others, have been standing on your shoulders for years, and I want you to know that I really do appreciate what you've done for me. If you ever get down to the Ozarks all the beer and Skittles are on me! Kindest Regards, Bill Stephenson Thanks! Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Brett, Thanks for the feedback. - A ::Compat addition that allows people to keep using a maximal amount of the old API if they need to. (Including a certain amount of plugins) Or maybe just do something like how perl5 turns on new version based features (e.g., use CGI::Application q/1.2.3/;). My goal there is to really start fresh, and have a minimal amount of extra stuff in the core. No one is being forced to upgrade, and changing a single line of code seems reasonable for those who want to upgrade the module without updating any of their other project code. - PSGI-native. I'm excited that Perl web frameworks are converging here. We'll be able to take advantage of PSGI Middleware that was designed with other frameworks in mind. Many things that were CGI::App plugins before are now better done done as PSGI Middleware. As a plugin author, you get the benefit of having more users who may be using other frameworks. The difference with CGI::App will be that PSGI will the *only* code path supported. Nice. I would like to warn that traditional persistent environments will continue to remain relevant, and I think it's a mistake to discount this. I assume you mean mod_perl and FastCGI? PSGI helps code to run in those environments in a clean way. In those cases, it's definitely preferable to the old way of having framework code that includes conditionals for each environment. The guts of CGI.pm are an example of that ugliness. Additionally, from what I have seen from the other frameworks, nothing solves anything in principle beyond what CAP does. Some make it easier to define runmodes or to set up dispatching, but you still need to properly create a proper MVC separation and set of supporting modules. It's the same amount of work no matter what you use. I disagree that it's the same amount of work no matter what choices you make. Some are easier to install, some are easier to learn, and some have more formality that provide ready-made discipline to help organize more complex projects. - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. It's already possible to write a CGI::App subclass based on Moose or Mouse, but like with PSGI, I think it's in our best interest to upgrade to first class support. I am not sure what this buys anyone, to be frank. I appreciate the frankness. :) I know that using these object layering might incite some sort of religious war. Ultimately, this decision is clearly in the hands of those who do the work. I have my reservations about moving away from Perlish idioms and towards the oop flavors of the week. Any core might be well served by avoiding any sort of meta object sugar over the long haul. Moose was first released over six years ago, so I don't think it's fair to call it's popularity weekly. With Any::Mouse, performance is good in CGI environments via Mouse, and also good in persistent environments with Moose. We've now reached a Moose tipping point where a project of any significant size is likely to be loading Moose or Mouse or Moo anyway, so whether to load them or not has become last of an issue. For example, if you want to access Amazon APIs via Perl, you'd likely choose Net::Amazon::S3, which loads Moose. If you use the modern Text::XSlate templating system, you'll be loading Mouse. If you want to conveniently access cookies in Test::WWW::Mechanize than you might use HTTP::CookieMonster, which loads Moo. Importantly, there's no requirement to use these in your own modules, or even switch from CGI::Application to the new project. I think my overall point is that CAP and what it provides is timeless. The pendulum swings both ways, and it would be nice to see CAP focus on improving its strengths and not trying to do what the other kids might be doing. I agree that there are timeless basic principles in there. I appreciate PSGI and the Moose APIs because there are helping bring the Perl web development community together by providing good options for re-using code between frameworks, with PSGI Middleware and Moose roles. - Plans to replace CGI.pm with request and response objects. As the CGI.pm maintainer, I could devote another full post to reasons why I don't to be using it in another 5 or 10 years. Details here are still to be determined as well. Immediately we would see the query() method replaced with a req method to represent a request object. HTTP has requests and responses. The idea of a query object is a CGI.pm'ism to leave behind. About every other Perl framework I've looked at models the response and request this way, and it's time we implemented this sensible design as well. I think I am not really clear on what change in perspective means. Is it truly a semantic
Re: [cgiapp] CGI::Application status update from the maintainer
- Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. This is tricky. Why is the env low-resourced? And if it is, what's wrong with targeting it with a low-overhead env such as non-Moose? I'm thinking primarily of these environments: - CGI, used in shared hosting accounts where there is persistent option - Automated tests, which like CGI, need to load modules each time. These environments also see non-persistent CGI::App use sometimes: - Cron scripts (I use CGI::App for cron scripts for convenience) - Interactive command-line scripts (I also use CGI::App for some of these which are part of a large website). I'm not thinking so much in terms hardware. A few years ago I benchmarked the start-up times of various Perl-based web building tools, which would apply to the environments above: http://mark.stosberg.com/blog/2008/11/startup-benchmarks-for-mojo-catalyst-titanium-httpengine-and-cgiapplication.html Since then, hardware has gotten faster, and SSDs are becoming more common. Today I benchmark Mouse taking .05 seconds to load on my laptop. That's price I think is completely reasonable to pay. Without using a timing tool, the difference in indistinquishable from instant. time -p perl -MMouse -e 1 these object layering might incite some sort of religious war. Ultimately, this decision is clearly in the hands of those who do the work. I have my reservations about moving away from Perlish idioms and towards the oop flavors of the week. Any core might be well served by avoiding any sort of meta object sugar over the long haul. I think my overall point is that CAP and what it provides is timeless. The pendulum swings both ways, and it would be nice to see CAP focus on improving its strengths and not trying to do what the other kids might be doing. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. This is important. See: - Class::Method::Delegate (no dependencies [actually Carp], no bugs) - Role::Tiny (ditto [actually Exporter], 1 bug) - Role::Basic (Storable, 3 bugs) - Moo::Role (various, 2 bugs) - Moose::Role (ditto, 52 bugs) But see what Role::Tiny has to say about Role::Basic. So Moose/Mouse are not actually needed, if smallness is a virtue. I also see that CGI.pm has over 80 open bugs, while Plack::Request/Plack::Response appear to have 2 open bugs in the Plack bug queue that apply to them, with both them appearing to be enhancement requests. The number of bug reports a project has seems to often be driven by popularity. There's also a certain accumulation that comes with age. The comparison above is misleading in any case, as as the small role solutions have just one module or so in the distribution, so those bugs are exactly about roles. The Moose bug queue is for the whole Moose project. Only about 5 or 6 that I see have role in the title of the bug reports. Also consider that CGI.pm has one person committing fixes for the 80+ bugs (for lack of interest from others, it seems), while the Moose project appears to have about 8 maintainers. On it's own, I don't think the general presence of bugs in a bug queue presents a great concern about the quality of project, although specific bugs certainly could. Are there specific bugs with Moose or Mouse roles that you find troubling? Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Mark On 09/09/12 10:28, Mark Stosberg wrote: - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. This is tricky. Why is the env low-resourced? And if it is, what's wrong with targeting it with a low-overhead env such as non-Moose? I'm thinking primarily of these environments: - CGI, used in shared hosting accounts where there is persistent option - Automated tests, which like CGI, need to load modules each time. These environments also see non-persistent CGI::App use sometimes: - Cron scripts (I use CGI::App for cron scripts for convenience) - Interactive command-line scripts (I also use CGI::App for some of these which are part of a large website). OK. Good points. I'm not thinking so much in terms hardware. A few years ago I benchmarked the start-up times of various Perl-based web building tools, which would apply to the environments above: http://mark.stosberg.com/blog/2008/11/startup-benchmarks-for-mojo-catalyst-titanium-httpengine-and-cgiapplication.html Since then, hardware has gotten faster, and SSDs are becoming more common. Today I benchmark Mouse taking .05 seconds to load on my laptop. That's price I think is completely reasonable to pay. Without using a timing tool, the difference in indistinquishable from instant. Agreed: .05 sec is nothing. time -p perl -MMouse -e 1 these object layering might incite some sort of religious war. Ultimately, this decision is clearly in the hands of those who do the work. I have my reservations about moving away from Perlish idioms and towards the oop flavors of the week. Any core might be well served by avoiding any sort of meta object sugar over the long haul. I think my overall point is that CAP and what it provides is timeless. The pendulum swings both ways, and it would be nice to see CAP focus on improving its strengths and not trying to do what the other kids might be doing. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. This is important. See: - Class::Method::Delegate (no dependencies [actually Carp], no bugs) - Role::Tiny (ditto [actually Exporter], 1 bug) - Role::Basic (Storable, 3 bugs) - Moo::Role (various, 2 bugs) - Moose::Role (ditto, 52 bugs) But see what Role::Tiny has to say about Role::Basic. So Moose/Mouse are not actually needed, if smallness is a virtue. I also see that CGI.pm has over 80 open bugs, while Plack::Request/Plack::Response appear to have 2 open bugs in the Plack bug queue that apply to them, with both them appearing to be enhancement requests. The number of bug reports a project has seems to often be driven by popularity. There's also a certain accumulation that comes with age. The comparison above is misleading in any case, as as the small role solutions have just one module or so in the distribution, so those bugs are exactly about roles. The Moose bug queue is for the whole Moose project. Only about 5 or 6 that I see have role in the title of the bug reports. Also consider that CGI.pm has one person committing fixes for the 80+ bugs (for lack of interest from others, it seems), while the Moose project appears to have about 8 maintainers. On it's own, I don't think the general presence of bugs in a bug queue presents a great concern about the quality of project, although specific bugs certainly could. Are there specific bugs with Moose or Mouse roles that you find troubling? Nope. I did not intend the # of bugs to say anything about the relative merits of the modules. It was all about (potential) user education. IMHO Role::Tiny looks like the best choice. -- Ron Savage http://savage.net.au/ Ph: 0421 920 622 # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Thank you, Rhesa. This is helpful. My last common on cgiapp_init and setup will be this. It's not simply how deeply inheritance can be, it's the fact that there are 2 explicit API methods for initializing an instance beyond what is provided for in the ancestor. For me, it'd make more sense to do a way with setup altogether and use a method similar to the init hook you mentioned below. I am sure MMWV, but I will take your advice below. Thanks for the help. Brett On Thu, Sep 6, 2012 at 12:04 PM, Rhesa Rozendaal p...@rhesa.com wrote: On 09/06/2012 04:48 PM, B. Estrade wrote: You're limited to 2 generations below CAP if you want to subclass without explicitly calling on SUPER because you have 2 explicit methods -cgiapp_init and setup. I am suggesting a way to provide any number of generations without having to call on SUPER. You're not limited to 2 levels of inheritance. The grandchild's SUPER calls the child's method, and the child's SUPER calls the parent's method. It'll work the same even when you add a grandchild. (At some point I'd start asking myself if inheritance is really the way I'd want to structure my application). Here is my real world use case. I split my applications into 2 parts; one amounts to the UI payload delivery, basically HTML that makes all calls asynchronously. The other is strictly non-UI and handles only asynchronous requests (i.e., the REST API). And I typically have this hierarchy: 1. WebCommon.pm (ISA CGI::Application; implements Authentication and common run modes) 2. WebApp.pm (ISA WebCommon; base class for the UI delivery or initial view) 3. WebAPI.pm (ISA WebCommon; base class for the REST API) From there, I may have another or even another 2 levels of WebApps or WebAPIs. In WebCommon.pm, I define cgiapp_init; in WebApps.pm and WebAPI.pm, I define a setup. Beyond that, I redefine setup with a call to $self-SUPER::setup - not something I really like doing. You'd be better off setting up your runmodes in an init hook. That's the way I do it in CA::Plugin::RunmodeDeclare. package WebCommon; use base 'CGI::Application'; __PACKAGE__-add_callback( init = sub { $_[0]-run_modes([ ... ]); }); package WebAPI; use base 'WebCommon'; __PACKAGE__-add_callback( init = sub { $_[0]-run_modes([ ... ]); }); package WebAPI::Stuff; use base 'WebAPI'; __PACKAGE__-add_callback( init = sub { $_[0]-run_modes([ ... ]); }); Then WebAPI has all the run modes of WebCommon, as well as its own run modes. And WebAPI::Stuff has those of WebAPI and its own. However, I'd ask myself if I really want to have all those parent run modes in the child app. I want to use CGI::Simple, but do not want to enable uploads app-wide. I have a subclass (WebAPI::UploadApp, say) where I do want to enable uploads. In WebCommon.pm, I have to do this: our $cgi; #= CGI::Simple-new; Don't do this. You need a query object that's an attribute of the current CA object. A package variable is going to have too wide a scope. sub cgiapp_get_query { use CGI::Simple (); $cgi = CGI::Simple-new(); return $cgi; } This is better written as: sub cgiapp_get_query { use CGI::Simple; return CGI::Simple-new; } Then in order to override that CGI::Simple to enable uploads, in WebAPI::UploadApp, I have to do this: sub cgiapp_get_query { my $self = shift; use CGI::Simple (); $CGI::Simple::DISABLE_UPLOADS = 0; $self::SUPER::cgi = CGI::Simple-new(); return $self::SUPER::cgi; } That code makes little sense. cgiapp_get_query is supposed to return a CGI compatible object. It's not supposed to change variables in another package. This is what you should do instead: sub cgiapp_get_query { local $CGI::Simple::DISABLE_UPLOADS = 0; return $_[0]-SUPER::cgiapp_get_query; } Granted, there is probably a more correct, cleaner, or better way to do this; if so, I am all ears. The only ugly thing about that is that package variable to influence upload behavior. It'd be prettier if CGI::Simple had an accessor for that, or a constructor argument. That's what you get for trying to be compatible with CGI.pm I guess ;) rhesa # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## #### # CGI::Application community mailing list #### ## To unsubscribe, or
Re: [cgiapp] CGI::Application status update from the maintainer
Richard, Thanks for the feedback. But since C::A first appeared we now have newer frameworks like Catalyst, Mojo, and the more recent Dancer (also in the process of being rewritten to embrace the Moose API). Given that Ron has already forked C::A I wonder if there is any point embarking on another? Accepting that Catalyst is not to everyones taste, and Dancer may not yet have the recognition and presence that Catalyst and Mojo/Mojolicious have as web frameworks, I'm wondering what advantage a revamped C::A under a new name will provide. I think each has it's own strengths. I looked at Mojo particularly closely, contributing doc and test patches along the way as I studied it. ( I was surprised to find that my contribution is still third highest by number of commits, although I haven't contributed since 2009: https://github.com/kraih/mojo/graphs/contributors ). In some ways their is convergance towards PSGI and Moose. I think that's a good thing, because there is now more re-use between frameworks. There's also more competition now among lightweight frameworks. Besides the one you mentioned, there is Web::Simple and Amon2, among many more less well known frameworks. I think CGI::App's basic design with stages and callbacks is worth carrying forward. I think a lightweight impementation of the Moose API is also worth supporting in the core, which is absent in Ron's fork. Finally, I think quite a number of people deployed CGI::Application and some of it's many plugins, and some of them like me would like a way forward to modernize their systems without a complete rewrite. One essential item for any web framework is a competent dispatcher, something I think compromises Dancer v1 (hopefully addressed in v2), essential for an application with a large number of run-modes (or equivalents). C::A::Dispatch or a core equivalent is a must IMO. I'm not sure if that is what you had in mind with global dispatching. I agree that dispatching has been central to web frameworks. By global dispatching I mean centralized dispatching-- having one place in your app to see all the URLs and what they app to. I call the default Cataylst style local dispatching-- placing the URIs that encompass the system next to the methods they map to. I like the design of CGI::Application::Dispatch::PSGI and don't currently have specific intents to change it. I've come across one other routing solution that appealed to me. Router::Simple has a nice OO syntax that's similar to what we use: https://metacpan.org/module/Router::Simple Amon2 then provides a nice DSL wrapper around it, so the resulting dispatch entries look like this: package MyApp::Web::Dispatcher; use Amon2::Web::Dispatcher::RouterSimple; connect '/' = 'Root#index'; connect '/my/'= 'My#index'; connect '/my/:action' = 'My'; https://metacpan.org/module/Amon2::Web::Dispatcher::RouterSimple Still, best wishes for C::A mark II if you decide to go through with it, Thanks! Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Snipped On Thu, Sep 06, 2012 at 09:12:40AM +1000, Ron Savage wrote: Hi Brett It would be really nice to merge in some bare bones Authentication and Authorization support - maybe ever by more fully developing CAP's lifecycle. Likewise. It's a pity a standard(!) way of doing this with CAP doesn't seem to have evolved /with the approval of all/. Here are some items I would like to see addressed. 1. scalability - it is unnecessarily awkward to have more than 2 levels of subclassing currently. This statement worries me. Could you please expand. Also, did you look at CGI::Snapp::Demo::Four::Wrapper, which easily wraps CGI::Snapp::Demo::Four. It's specifically a (simple) demo of sub-classing. Direct subclass of CAP uses cgi_init; child of subclass uses setup; anything else must call SUPER::setup. How does this differ from any other class which uses sub-classing? The parent method is either completely overridden or called /and/ partially overridden. Or am I missing something? What I mean is that there are 2 methods that basically do the same thing. If you have MyApp (ISA CGI::Application), you would initialize runmodes and whatnot via cgiapp_init. Say you subclass MyApp to get MyApp::Foo, but want to keep what is going on in MyApp::cgiapp_init; but you have your own specific MyApp::Foo runmodes. You'd most cleanly do this by defining MyApp::Foo::setup. Now, what if you want to subclass MyApp::Foo into MyApp::Foo::Derp, but you have some Derp specific runmodes. You end up having to redefine cgiapp_init or setup; in either case, you're going to have to make an explicit call to SUPER::cgiapp_init or SUPER::setup. You're limited to 2 generations below CAP if you want to subclass without explicitly calling on SUPER because you have 2 explicit methods -cgiapp_init and setup. I am suggesting a way to provide any number of generations without having to call on SUPER. Here is my real world use case. I split my applications into 2 parts; one amounts to the UI payload delivery, basically HTML that makes all calls asynchronously. The other is strictly non-UI and handles only asynchronous requests (i.e., the REST API). And I typically have this hierarchy: 1. WebCommon.pm (ISA CGI::Application; implements Authentication and common run modes) 2. WebApp.pm (ISA WebCommon; base class for the UI delivery or initial view) 3. WebAPI.pm (ISA WebCommon; base class for the REST API) From there, I may have another or even another 2 levels of WebApps or WebAPIs. In WebCommon.pm, I define cgiapp_init; in WebApps.pm and WebAPI.pm, I define a setup. Beyond that, I redefine setup with a call to $self-SUPER::setup - not something I really like doing. 3. a more fully developed plugin/event system; I think this goes along with #2 (i.e., a few more hooks), but in addition to this I have always thought it would be useful to have some sort of mechanism through which plugins might be able to query one another. A good example (and actually the main motivation for #2 and #3) are the CAP Authorization and Authentication plugins. The short list of troubles I have had with using these two are: * when used together, Authorization is called before Authentication, making it awkward to handle authorization errors of unauthenticated guests (or maybe Authz assumes an authenticated session); * default behavior of Authz is to query directly the Authorization plugin instance for a username; this works fine in that situation, but there is no clear way for plugin A to make information available to plugin B; There's no doubt they are awkward. I'd argue the underlying CAP structure is sound, and just this part need a bug re-think. 4. more flexibility with the query object...err response object; I've run into some hoops to jump through when I wanted to use CGI::Simple and be able to upload capabilities on or off in a sub class. It'd help if you could expand on this issue. I want to use CGI::Simple, but do not want to enable uploads app-wide. I have a subclass (WebAPI::UploadApp, say) where I do want to enable uploads. In WebCommon.pm, I have to do this: our $cgi; #= CGI::Simple-new; sub cgiapp_get_query { use CGI::Simple (); $cgi = CGI::Simple-new(); return $cgi; } Then in order to override that CGI::Simple to enable uploads, in WebAPI::UploadApp, I have to do this: sub cgiapp_get_query { my $self = shift; use CGI::Simple (); $CGI::Simple::DISABLE_UPLOADS = 0; $self::SUPER::cgi = CGI::Simple-new();
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Brett On 07/09/12 00:48, B. Estrade wrote: What I mean is that there are 2 methods that basically do the same thing. If you have MyApp (ISA CGI::Application), you would initialize runmodes and whatnot via cgiapp_init. Say you subclass MyApp to get MyApp::Foo, but want to keep what is going on in MyApp::cgiapp_init; but you have your own specific MyApp::Foo runmodes. You'd most cleanly do this by defining MyApp::Foo::setup. Now, what if you want to subclass MyApp::Foo into MyApp::Foo::Derp, but you have some Derp specific runmodes. You end up having to redefine cgiapp_init or setup; in either case, you're going to have to make an explicit call to SUPER::cgiapp_init or SUPER::setup. You're limited to 2 generations below CAP if you want to subclass without explicitly calling on SUPER because you have 2 explicit methods -cgiapp_init and setup. I am suggesting a way to provide any number of generations without having to call on SUPER. Rhesa has replied with one (slightly more complex) way of doing things. Here is another: package WebCommon; use base 'CGI::Application'; sub cgi_init # or setup { $self - web_common_init; } package WebAPI; use base 'WebCommon'; sub cgi_init # or setup { $self - web_api_init; } package WebAPI::Stuff; use base 'WebAPI'; sub cgi_init # or setup { $self - web_api_stuff_init; } The 3 new subs can be stand-alone or call each other or call common code. They can do whatever you think best. The point is that the sub-class cgi_inits are overridden by the /normal/ operation of CAP, and hence are called at the appropriate time /automatically/. Obviously you can call SUPER::cgi_init or SUPER::anything if you wish. (Sometimes of course calling a super class's method is mandatory. For instance, with CGI::Snapp, a sub-class must call SUPER::_init($arg), as in the demo. But that's to initialize object-level variables, having nothing to do with what we're talking about.) The problem is that SUPER::* is a way of sharing /all/ the code in the super class's cgi_init. If you don't wish to do that, then do as I've indicated above, and just share none or some of the code via web_common_init etc. You really do have a variety of ways to work. Lastly, there is no limit on the depth of nesting possible. -- Ron Savage http://savage.net.au/ Ph: 0421 920 622 # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
Thank you, Mark. Responses are inlined. On Tue, Aug 28, 2012 at 11:27:04PM -0400, Mark Stosberg wrote: Hello Everyone. I'll start with a apology about not being as present as I intended. Messages from this list were not coming directly to my Inbox for some time, and it took me longer than I wanted to get that addressed. Starting today, messages should be going back in my Inbox again, and I will attempt be more responsive here. I'm still alive and well, and use and support CGI::Application every day at work. I'm also now the primary maintainer of CGI.pm. While it's only a part of the CGI::Application framework, it has substantially more lines of code, as well as more bugs and bug traffic. More of my maintenance time has been spent maintaining that lately. I appreciate the fork that Ron Savage recently published, because it's good to explore options, and it's easiest to evaluate options if they are complete. I also agree with the spirit of it. It's time for the next generation of the framework, one that breaks compatibility in some places to move the whole forward. I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. It was interesting to find Ron's fork which had been developed independently and in parallel, to see where we agreed and where we differed. It strikes me that CAP is more of a way or standard than any particular implementation, even though I think it could certainly be standardized or have that one true reference implementation. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. - A ::Compat addition that allows people to keep using a maximal amount of the old API if they need to. (Including a certain amount of plugins) Or maybe just do something like how perl5 turns on new version based features (e.g., use CGI::Application q/1.2.3/;). - PSGI-native. I'm excited that Perl web frameworks are converging here. We'll be able to take advantage of PSGI Middleware that was designed with other frameworks in mind. Many things that were CGI::App plugins before are now better done done as PSGI Middleware. As a plugin author, you get the benefit of having more users who may be using other frameworks. The difference with CGI::App will be that PSGI will the *only* code path supported. Nice. I would like to warn that traditional persistent environments will continue to remain relevant, and I think it's a mistake to discount this. Additionally, from what I have seen from the other frameworks, nothing solves anything in principle beyond what CAP does. Some make it easier to define runmodes or to set up dispatching, but you still need to properly create a proper MVC separation and set of supporting modules. It's the same amount of work no matter what you use. - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. It's already possible to write a CGI::App subclass based on Moose or Mouse, but like with PSGI, I think it's in our best interest to upgrade to first class support. I am not sure what this buys anyone, to be frank. I know that using these object layering might incite some sort of religious war. Ultimately, this decision is clearly in the hands of those who do the work. I have my reservations about moving away from Perlish idioms and towards the oop flavors of the week. Any core might be well served by avoiding any sort of meta object sugar over the long haul. I think my overall point is that CAP and what it provides is timeless. The pendulum swings both ways, and it would be nice to see CAP focus on improving its strengths and not trying to do what the other kids might be doing. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. - Templating APIs removed from core, for now. We'll get a new templating API, although the details are still TBD. - Plans to replace CGI.pm with request and response objects. As the CGI.pm maintainer, I could devote another full post to reasons why I don't to be using it in another 5 or 10 years. Details here are still to be determined as well. Immediately we would see the query() method replaced with a req method to represent a request object. HTTP has requests and responses. The idea of a query object is a CGI.pm'ism to leave behind. About every other Perl framework I've looked at models
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Brett I'm snipping this email because I expect to pen several replies. On 06/09/12 03:57, B. Estrade wrote: Thank you, Mark. Responses are inlined. - A ::Compat addition that allows people to keep using a maximal amount of the old API if they need to. (Including a certain amount of plugins) Changing the API and keeping a back-compat API means not changing the API in the (new) back-compat part of the code. This is always a difficult decision. My basic feeling is if people stick with the (new) back-compat API they might as well have stuck with the old (back-compat!) API. So the question is, why not switch to the new API. Perhaps because some people want to switch in small steps. My policy is that if the switch is on, commit to the whole of the new API. Or maybe just do something like how perl5 turns on new version based features (e.g., use CGI::Application q/1.2.3/;). - PSGI-native. I'm excited that Perl web frameworks are converging here. We'll be able to take advantage of PSGI Middleware that was designed with other frameworks in mind. Many things that were CGI::App plugins before are now better done done as PSGI Middleware. As a plugin author, you get the benefit of having more users who may be using other frameworks. The difference with CGI::App will be that PSGI will the *only* code path supported. Nice. I already use Plack::Middleware::(ContentLength, Session and Static), in various situations, when using CGI::Snapp. You do realize that's possible, right? I would like to warn that traditional persistent environments will continue to remain relevant, and I think it's a mistake to discount this. Absolutely. My policy is to make available tools for all programmers, not just those who adopt the latest mechanism. After all, there is always going to be a pool of programmers whose work environment and/or personality is too conservative to let them be amongst the first to switch. They may in fact make that switch years after the leaders to. Or, any of us may be employed to support old code. Additionally, from what I have seen from the other frameworks, nothing solves anything in principle beyond what CAP does. Some make it easier to define runmodes or to set up dispatching, but you still need to properly create a proper MVC separation and set of supporting modules. It's the same amount of work no matter what you use. This is a marvellous point. I've looked a Mojo a number of times, but despite its great cleverness, it's major use seems to be smart switching of requests. Likewise, there are now quite a new routing-oriented packages available. They all attack the same problem, but it's a small part of a whole app. And the classic CGI::Application::Dispatch (copied to CGI::Snapp::Dispatch) is a beautifully simply way to do that. - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. This is tricky. Why is the env low-resourced? And if it is, what's wrong with targeting it with a low-overhead env such as non-Moose? It's already possible to write a CGI::App subclass based on Moose or Mouse, but like with PSGI, I think it's in our best interest to upgrade to first class support. I am not sure what this buys anyone, to be frank. I know that using Me neither. For control freaks it obviously gives greater, er, control, over parameters and attributes, but that alone does not guarantee great apps. these object layering might incite some sort of religious war. Ultimately, this decision is clearly in the hands of those who do the work. I have my reservations about moving away from Perlish idioms and towards the oop flavors of the week. Any core might be well served by avoiding any sort of meta object sugar over the long haul. I think my overall point is that CAP and what it provides is timeless. The pendulum swings both ways, and it would be nice to see CAP focus on improving its strengths and not trying to do what the other kids might be doing. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. This is important. See: - Class::Method::Delegate (no dependencies [actually Carp], no bugs) - Role::Tiny (ditto [actually Exporter], 1 bug) - Role::Basic (Storable, 3 bugs) - Moo::Role (various, 2 bugs) - Moose::Role (ditto, 52 bugs) But see what Role::Tiny has to say about Role::Basic. So Moose/Mouse are not actually needed, if smallness is a virtue. - Templating APIs removed from core, for now. We'll get a new templating API, although the details are still TBD. Yep. - Plans to replace
Re: [cgiapp] CGI::Application status update from the maintainer
Hi Mark, I also use C::A everyday - my main application that I wrote and maintain is a C::A. You are of course right that C::A uses some out-of-date procedures like the query method. But since C::A first appeared we now have newer frameworks like Catalyst, Mojo, and the more recent Dancer (also in the process of being rewritten to embrace the Moose API). Given that Ron has already forked C::A I wonder if there is any point embarking on another? Accepting that Catalyst is not to everyones taste, and Dancer may not yet have the recognition and presence that Catalyst and Mojo/Mojolicious have as web frameworks, I'm wondering what advantage a revamped C::A under a new name will provide. One essential item for any web framework is a competent dispatcher, something I think compromises Dancer v1 (hopefully addressed in v2), essential for an application with a large number of run-modes (or equivalents). C::A::Dispatch or a core equivalent is a must IMO. I'm not sure if that is what you had in mind with global dispatching. Still, best wishes for C::A mark II if you decide to go through with it, and looking forward to seeing the draft code later this week :) On 29/08/2012 04:27, Mark Stosberg wrote: Hello Everyone. I'll start with a apology about not being as present as I intended. Messages from this list were not coming directly to my Inbox for some time, and it took me longer than I wanted to get that addressed. Starting today, messages should be going back in my Inbox again, and I will attempt be more responsive here. I'm still alive and well, and use and support CGI::Application every day at work. I'm also now the primary maintainer of CGI.pm. While it's only a part of the CGI::Application framework, it has substantially more lines of code, as well as more bugs and bug traffic. More of my maintenance time has been spent maintaining that lately. I appreciate the fork that Ron Savage recently published, because it's good to explore options, and it's easiest to evaluate options if they are complete. I also agree with the spirit of it. It's time for the next generation of the framework, one that breaks compatibility in some places to move the whole forward. I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. It was interesting to find Ron's fork which had been developed independently and in parallel, to see where we agreed and where we differed. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. - A ::Compat addition that allows people to keep using a maximal amount of the old API if they need to. (Including a certain amount of plugins) - PSGI-native. I'm excited that Perl web frameworks are converging here. We'll be able to take advantage of PSGI Middleware that was designed with other frameworks in mind. Many things that were CGI::App plugins before are now better done done as PSGI Middleware. As a plugin author, you get the benefit of having more users who may be using other frameworks. The difference with CGI::App will be that PSGI will the *only* code path supported. - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. It's already possible to write a CGI::App subclass based on Moose or Mouse, but like with PSGI, I think it's in our best interest to upgrade to first class support. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. - Templating APIs removed from core, for now. We'll get a new templating API, although the details are still TBD. - Plans to replace CGI.pm with request and response objects. As the CGI.pm maintainer, I could devote another full post to reasons why I don't to be using it in another 5 or 10 years. Details here are still to be determined as well. Immediately we would see the query() method replaced with a req method to represent a request object. HTTP has requests and responses. The idea of a query object is a CGI.pm'ism to leave behind. About every other Perl framework I've looked at models the response and request this way, and it's time we implemented this sensible design as well. - The popular and small ::Forward() and ::Redirect() plugins will be merged into the core. As part of considering the future of CGI::Application, I did consider just dropping it.
Re: [cgiapp] CGI::Application status update from the maintainer
On Wed, Aug 29, 2012 at 6:27 AM, Mark Stosberg m...@summersault.com wrote: I'll start with a apology about not being as present as I intended. No need for that. I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. My bike-shed request is to avoid the word CGI :) Otherwise I applaud your work and plans! Thank you! regards Gabor # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On 29.8.2012 8:26, Gabor Szabo wrote: I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. My bike-shed request is to avoid the word CGI :) I agree that well chosen name is crucial for taking over the world ;) -- Jiří Pavlovský # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. My bike-shed request is to avoid the word CGI :) Gabor, Thanks for the feedback. Your request will be granted. Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
Re: [cgiapp] CGI::Application status update from the maintainer
On 08/28/2012 11:27 PM, Mark Stosberg wrote: I look forward to being conversation with you all more about this. I'll set a goal to release the first code-as-draft for my proposal within a week, and look forward to your feedback to sculpt it into a releasable form. I agree with just about everything you've mentioned here Mark. I've been thinking myself that C::A needed to be reinvented as something more modern but that still had the same flavor. My only advice is that since you'll really only have this one time to make a break like this from the past, don't feel bad about breaking backward compatibility. From your email it doesn't seem like you do, just wanted to make sure that you knew we'd support something like that. And like Gabor said, avoid the word CGI :) I know we've been down the naming rabbit hole before and it makes all the bikeshedders come out, a good unique, google-able name would be nice. And naming writes go to the man who does the work, so enjoy :) -- Michael Peters Plus Three, LP # CGI::Application community mailing list #### ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp## #### ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ####
[cgiapp] CGI::Application status update from the maintainer
Hello Everyone. I'll start with a apology about not being as present as I intended. Messages from this list were not coming directly to my Inbox for some time, and it took me longer than I wanted to get that addressed. Starting today, messages should be going back in my Inbox again, and I will attempt be more responsive here. I'm still alive and well, and use and support CGI::Application every day at work. I'm also now the primary maintainer of CGI.pm. While it's only a part of the CGI::Application framework, it has substantially more lines of code, as well as more bugs and bug traffic. More of my maintenance time has been spent maintaining that lately. I appreciate the fork that Ron Savage recently published, because it's good to explore options, and it's easiest to evaluate options if they are complete. I also agree with the spirit of it. It's time for the next generation of the framework, one that breaks compatibility in some places to move the whole forward. I started writing my own fork over a year ago in hopes of having something to share around the time for YAPC 2011. While I needed to put that on hold for a while, It's now on the verge of the initial release. It was interesting to find Ron's fork which had been developed independently and in parallel, to see where we agreed and where we differed. Here are the key points I have mind for the update I'll be publishing soon: - A new name space, to avoid confusion and problems with API changes. - A ::Compat addition that allows people to keep using a maximal amount of the old API if they need to. (Including a certain amount of plugins) - PSGI-native. I'm excited that Perl web frameworks are converging here. We'll be able to take advantage of PSGI Middleware that was designed with other frameworks in mind. Many things that were CGI::App plugins before are now better done done as PSGI Middleware. As a plugin author, you get the benefit of having more users who may be using other frameworks. The difference with CGI::App will be that PSGI will the *only* code path supported. - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings much of that API to lower resource environments, like the CGI environment where CGI::Application has always performed well. It's already possible to write a CGI::App subclass based on Moose or Mouse, but like with PSGI, I think it's in our best interest to upgrade to first class support. Just as PSGI Middleware presents a new opportunity for code re-use, Moose/Mouse roles present another alternative to plugins that can be shared between frameworks. For example, methods for logging, database access and config data are all good candidates to be implemented as roles. - Templating APIs removed from core, for now. We'll get a new templating API, although the details are still TBD. - Plans to replace CGI.pm with request and response objects. As the CGI.pm maintainer, I could devote another full post to reasons why I don't to be using it in another 5 or 10 years. Details here are still to be determined as well. Immediately we would see the query() method replaced with a req method to represent a request object. HTTP has requests and responses. The idea of a query object is a CGI.pm'ism to leave behind. About every other Perl framework I've looked at models the response and request this way, and it's time we implemented this sensible design as well. - The popular and small ::Forward() and ::Redirect() plugins will be merged into the core. As part of considering the future of CGI::Application, I did consider just dropping it. I maintain it, but lack the emotional attachment of being the original author. I stepped back and took a look at it from the distance and compared it to alternatives. Outside of the few details I'd like to change, I find the core of it still offers a unique combination of design properties that I think are worth taking forward: - I think the flow of the execution stages works very well. I'm talking about init, setup, prerun, run, postrun, teardown, as they are implemented in new() and run(). - Lightweight / fast start up time. - Simple. Less code to learn, less chance for bugs. - Global dispatching. That is, a single central table, rather than storing dispatch details locally, with each run mode. - Ability to scale up. I find CGI::App suitable for large projects as well as small. There's also a great community of people and plugins around CGI::App as well. I look forward to being conversation with you all more about this. I'll set a goal to release the first code-as-draft for my proposal within a week, and look forward to your feedback to sculpt it into a releasable form. Thanks, Mark # CGI::Application community mailing list #### ## To unsubscribe, or change your message