Organizing Script Includes in ServiceNow | Share the Wealth
so i've taken some code that i built for one particular customer for one particular implementation of hardware asset management and that's sort of what i'll use as an example of how i structure my code which a lot of it goes to what we're gonna what i'll mention in these in these few slides so cool let's get started so it's about organizing script includes i know we have a very very wide range of skill sets in this meeting so it's going to start very basic and it's going to move up from there like here's our agenda here's our agenda so i have a quick disclaimer that i'll put out there that's just about these are my opinions so not necessarily are these any sort of golden book i'll give a definition of what script includes are i'll talk about why sort of the purpose of organizing your script includes and why it's best practice and why they should be organized in a meaningful way and then we'll go over just some principles to help you keep your code i guess things to think about to help you keep your code as organized as possible whenever you're building it hopefully i can field questions throughout because i want this to be as interactive as as possible so if you have questions or if you need clarification please just let me know during the session and uh we can start conversations as we go all right so like i said quick disclaimer it's going to be an opinionated session so these are my opinions a lot of this is just my opinion so please don't take offense if i present an idea that you may not fully agree with i don't think anyone would take offense but i just don't want you to think that i'm saying this is the only way so what we're doing here is giving you ideas and telling you what's worked for me over the years right i'm going to do my best to explain it as we go through how i sort of got to all of my thoughts and opinions and ideas but you know if i missed something p please feel free for me to you know to ask me to clarify and you can always reach out to me after this please i mean a lot of you reach out to me all the time anyway so but if you need to reach out to me for anything please just let me know so we'll start with the definition like i said very very basic of script includes right so what is the script include and this is a question that i had my first day in servicenow like i had no idea what a script include was i was told to go build a script include and sort of how to use it and that it was server-side but i didn't realize that what it really is is a place like a repository for your code right so you can think of that as a file system of of code files if you were hosting your own web the script includes a server side of all of that so very simply they are records that contain javascript that runs on the server i don't differentiate here what type of javascript it's just some some javascript that will run on the server it can be something as simple as a single function or it can be a gigantic class of functions some of the stuff service now builds runs that entire spectrum i personally don't believe script includes should ever be one function i don't like that idea because they think script includes should again they're the cornerstone of your organization of your code in the platform so calling one function from a script include that function likely belongs somewhere and it doesn't belong by itself right it likely is part of a bigger idea and belongs in you know in a class or another script of glue that helps express that idea cool script includes can also be called from client scripts right but they're called through glide ajax so glide ajax sends the parameters you pass into it to the server gets the information from the server and then passes that back out to you to go to the client so you know ajax should always be run asynchronously in fact in apps now you cannot run glide ajax asynchronously but you used to be able to and you still can in global even though it's not documented you can still do get xml weight which will allow it to be synchronous sometimes that's useful but most times it's not and then script includes just try to think of them like i said as the primary building block of reusable code in servicenow right so there's client side stuff too and there's there's ui scripts that we can build that act sort of like like script includes but script includes are really the core of everything because we do most of our processing most of our our data crunching on the server not on the client so yeah and script includes being that they run on the server for those of you that don't understand what that means really that you know server side is is this is basically it gets compiled into java using the rhino engine and that java then runs on the server on the servers that servicenow hosts their their instances on so the apis are slightly different than what you have available to you on the client client is based on the browser so if i'm in chrome i may have the latest and greatest and if i'm in ie i know i don't have the latest and greatest so the apis are a little bit different even between clients but they're definitely different between clients and the server now es5 ecmascript 5 is the the official latest code that is supported on the server but there is some support for es6 right like i think includes is is one of those that is an es6 function that you can use within the es5 server code because they've done some polyfills which polyfills are just functions that servicenow may have had or we could even add them but they're added to that server code base to be used sort of so to backfill things that have not been implemented in the on the server rhino engine yet hopefully that makes sense okay so that's the definition of scripting just a record just holds javascript that javascript loads and runs on the server so purpose right of organizing script includes a lot of times i show people things that i've built like script include wise like libraries that are built for for implementations and they're people are shocked at how many script includes i may create well i have a core belief in one of these principles we're about to mention the dry principle do not repeat yourself principle right so that's one of them code should be defined one time in one place any time that code needs to be used it's referenced from that one place so if for some reason i need to change that functionality in the future i come and change it in one place rather than 50 places so if i need even even if i'm in a business rule and i need something as simple as let me get the current user's phone number well that that is a theme right that that likely could be put into a script include about users that allows me to get information about users and could be reused in the future if i ever need to get a phone number again so rather than putting a function or even doing an inline glide record call within that business rule it's always going to be best practice to say let me go ahead and create a script include for that right first before i create that script include let me search the script includes to see if somebody else has already created that one or if servicenow already has a util that does that for me two right so lots and lots of script includes get created some of them are very small and only have a couple functions one or two functions some of them are larger and i'll kind of show you a good example of that with the library that i have that i'm going to show everyone so anyway do not repeat yourself so when this is adhered to really really strictly you can see how it helps reduce defects as well as development effort right so as an architect of a project if i am working with a couple of tcs and i sort of lay out how we're gonna structure the code in our in that implementation and i tell them hey i've already got a function that handles these things that you're probably gonna have to do in this workflow well now they can just go to that grab that that function and use that within their workflow every time that they need to get a certain piece of information so that's how it reduces efforts and any when you're maintaining in the future because we end up maintaining most of our solutions right most of our implementations and solutions so it helps us in the future as well as we carry on the time that it takes to step away and say i'm going to put that into a script include rather than just allowing the code to sit where the code sits i promise you in the long run is going to pay off in space i promise you been down this road i've been down both pathways putting things in script includes is always the better answer and even though it may take five minutes to put to create that script include and put the code in that script include you'll thank yourself in the future right whenever you have to maintain it so yeah keep everything and the way that it helps reduce defects is that it's only defined one place and so once you've had that code tested thoroughly it's tested thoroughly and there's not 10 different places where you may be trying to do the same thing that you need to keep in your mind to say i need to go update those things and make sure all of them are up to par with with you know what what the latest and greatest is on changes that we've made per uh the customer's request so you change it in one place that one place is already tested now you only have to test that one place again because you know if that function is always going to produce the same value or or values then you know your downstream things are going to work if you've already accounted for that from that one piece of code that you're changing right so overall maintenance and defects just really get cleared up as you build a library out like this okay cool and so that i'm kind of coming to the conclusion here right so you know there's the dry principle when dry is adhered to it minimizes defects and reduces overall development effort thus if you keep your code base organized by using the drive principle or one of that's just one of the principles but by using the drive principle your code base is going to have less defects and take less effort to maintain just by principle hey david can i give a real world example of this 100 sir so i was tasked with creating basically a custom app and it ended up having like three different parts to it one which was a widget one was a back end load in an import set and this principle actually saved us because we had specific code that had to push stuff through ire identification reconciliation engine and we ended up having to write basically the same code in four different areas that all had different update methods happening so by putting it into a script include a lot of what you just called out here was actually saving us overall because you know when we had to make one change we didn't have to do it in four different places right it also helps when you have like three or four different people doing different things i had sarah doing the ui side myself doing the load inside and someone else doing elsewhere we had one place where i could control that specific expertise block that i knew how to do right so it really really really really helped yeah great example and you know the the danger in that as well is that if somebody doesn't have a full picture the complete picture of what's going on architecturally with that project that you're working on which not everyone always does then there is the chance that duplication can occur because you know person b just doesn't know that person they already created that function so this is why team communication during a project during an implementation is absolutely critical and architects passing down their vision to to technical consultants is absolutely key so if you ever have questions i would say always search the script include code base first to see if anything's out there sort by updated you'll see stuff that was created by your team you'll see stuff that may you know may adhere to what you're trying to do here and i i would look into that thoroughly before moving on with creating something talk to the architect hey is this does this sound good like do we have a bit a need to make this a bigger script include with different functions in it how should i structure this right rather than just putting stuff in in a business rule or elsewhere you know ui action or business rule where server-side code is called i would make the argument that if you're not calling glide system or other native apis to servicenow directly and that's all you're doing then you need to put in a script include and that's excluding glide records because i will say i think glide record calls should always be in a function and if they're in a function that function should probably go into a script include one of the reasons i say glide records should always be in a function is because then you don't have these nested glide record calls that become so problematic and there's no problem calling your cloud record gr if it's within a function that is named properly you don't have to worry about what the name of that that cloud record is right that's something that i see on linkedin constantly and i just completely disagree with it that the problem that people are having has nothing to do with what they're naming glide records it has everything to do with how things are are structured you know don't put gr1 and sgr2 and gr3 inside of that gr1 that's going to lead to major problems i promise you every time so that's the purpose that's why we're here so now we go into some principles these are where i get really opinionated so you know i i i'm a firm believer in that good and respectful conflict is a great thing because we all come out better from it so you know if we have things that you guys want to that you disagree on let me know please okay so i say always build script includes as classes rather than single functions i've already mentioned this and again this is because the nature of script includes is to be a repository not if it can be a single function and servicenow does this all the time especially their legacy code which i guess i can you know sort of brush off as legacy code but a lot of their reference qualifiers and things like that are single functions and it just seems so inefficient and so difficult to maintain make a reference qualifier script include right make a reference fire a reference qualifier class that allows you to do reference qualifiers for itsm you know maybe call that itsm ref call right and then put tons of reference qualifiers all within that one the script include and now you know what's called every time you need a reference qualifier for something that's itsm it's probably in there if it's not you add the function right so a class should contain functions that make sense in the context of the class as well so if i have a class called user group and i'm doing things associated with the user group table such as insert update get things like that from that table i'm not going to put a get user by id function in there because it doesn't make sense in the context of that class what does make sense is having another script include called user that allows me to get the user and i know get user by id as a glide system thing but it allows me to do things that are user related i can then use that script include within my user group script include as a reference i see as a reference calling it so that it's only defined in one place and everything within the user group script include is themed or you know has that common context of user group all right put everything in a function like i said everything that's not native so like if i'm in a ui script and i need to you know update a state i can do current dot state equals whatever current dot updates you know set my redirect that's all native code that's all in the api that's perfect let's do that i don't need to define that anywhere else the service now already has all of that defined outside of that if it's not something like let's say i need to do processing on some record behind the scenes that should absolutely be broken out into a script include because you'll likely need it somewhere else in the future or no okay so when you think your function is small enough make it smaller that goes into this next idea of that a function should do one thing and it should do one thing very very well so if you have a function to create an incident that's all that function should do it shouldn't first do validation on 50 fields and then create an incident you should have a function that you pull out of that to say validate you know incident data and then call that first within that create incident function so that one that makes sense because validation code may not always make sense right off the bat but it makes sense if it's packaged in a function that's named properly right so it makes sense being in that in the other function your function's still only doing one thing ultimately it's only creating the incident it could it can abstract things out outside of that that core function like doing the validation the check on validation has to happen as part of the creation but it doesn't have to happen in the same function as the creation okay that's probably a bad example but we'll go through code that i'll kind of show you what i'm talking about so if that code can be broken down into any sort of logical blocks that aren't 100 related to what you're doing in that function break it out into it into a new function and then that broken out function if it has a theme or a context or a theme that doesn't make sense where it is break it out into its own script include so that now you're you're really complying with because you know for instance the validate incident data right that i just used as an example well that could likely go into its own script include called incident validator something like that naming is so difficult by the way but incident validator because i'm going to have other code that is going to create incidents at some point as well and i may need to validate different fields so why don't we make that a new script include that takes in a parameter to say what i need to validate and then make that a validation class all by itself and then pass that into the incident script include to where it can be used and it can be used multiple times right yeah so write up right write functions to do a single thing that's a lot lot lot harder than it sounds i know not everything i write is like that it can't be because sometimes you don't realize that you're you're actually mixing things up but that's why we are are constantly refactoring as well right constantly making our code better so when we go in and we're maintaining our code and we realize oh why how did i do that well i can change that i can i can rather than just continuing to maintain something that i know is wrong i can fix it so i don't have to fix it and make classes as generic as possible so they can be reused throughout your library now that's not going to be true of every class some classes are going to have to be very specific but they should be built upon classes that are very generic one of the classes that i'll show you is one that i've built and i use i've used with multiple customers that allows me to more easily get and work with glide records so rather than you know every one of my script includes having you know five or six let's let's say i have five script includes that all correspond with the table right let's say incident change problem you know where i'm getting that each one of those then has multiple functions in it update create gets i get all whatever right all of those functions well why would i do a glide record call in each one of those when i can just abstract that glide record call out somewhere else and call it as one single line in my script includes and then everything that where it's abstracted to is tightly tightly controlled i know i'm not going to hit any errors because i've coded it that way that if something fails it's going to fail silently or it's going to throw an error and i know when it's going to throw an error right so i know how to handle everything that i'm doing from from that code that's also a way to get around apis that are third party that you have no control over right so one of the things that i'm going to show you in my code is a couple of comments that i added just because it's in it's a servicenow api that just by the name of it you can't really tell what it's doing so i add a little comment but another way around that is to encapsulate that in a function that does tell you exactly what it does right because it doesn't matter what code is called within that function as long as the function name tells you what it does then then you're good you're in a good place okay so anyway make make classes as generic as possible for what they're doing so that they can be reused okay naming i i hate naming and i don't know it's the worst thing that we do it really is and it takes the longest time if you're doing it right you know anyone can put a two on the end of something or three on the end of something but that doesn't tell me what what your intention is tell me what your intention is please tell me what your intention is and please don't abbreviate unless it is an industry recognized abbreviation config that's a great industry recognized abbreviation gr is a great abbreviation but you know calling your parameters that you're passing in a b and c except for sort you can do that when you're doing a sort function outside of that that just doesn't make any sense i don't know what a b and c are right or and there's nothing they give it purpose yes sir can i make one suggestion also yeah yeah i i you'd be so surprised how often i see misspelled variables and stuff oh yeah in in code and it's really embarrassing when it's like somebody who's you know who's on our team and we find it and but like be i i see it so often but well maybe i even do it too but i'm sure we've all done it no don't even like yeah even like checking the spelling on your own variables and stuff is is good to do so i thought into them oh go ahead good game i was gonna say so the flip side of that is when you don't notice that and you write like 400 lines of code it can be very difficult and kind of sketchy to go back and fix that and because you're afraid you're going to actually create defects right find and replace find the results and that that's exactly what i do but there are those times where you're on like the fifth update of a functionality you put in and one time like the third time you caused a defect because you were just rushing too much and then it starts to get in your head a little bit like okay i see this but this is such a minor change and will it end up causing a defect somewhere else because i don't notice something right so i agree with you spelling's really important but if you've already built something out and something's misspelled don't make it a priority to necessarily go in there and just fix that one spelling for the sake of doing it right i i would disagree i i feel like refactoring should be like a scrum activity in development you know we i mean yeah you're always going to like have well so i don't want to derail this sorry no yeah i mean i think it would be fun to take this off but robert i lean more towards what jeff is saying that i will fix it because that i just my ocd will actually make me itch through my skin if i leave it like that most likely but yeah right i mean not not only abbreviations but yeah there are misspellings when you see a misspelling and you know if you're really paying attention to how you're naming that variable you're probably less likely to have a misspelling right one thing that that actually brings to mind is aside from just abbreviations some people also sometimes put names in there that just have a different letter right like instead of class c-l-a-s-s and says reserve word let's use k-l-a-s-s well that's just not a good idea there's probably a better way that that could be represented than just putting a k right so be as descriptive as you possibly can and when you look at it if you don't initially see oh i know exactly what that is and what i'm trying to do there probably rename it probably say how how can i make it something that i that i understand at a glance right because remember the goal here is not to build code for yourself it's to build code for the person coming behind you who you have no idea what their skill level is going to be you have no idea if they're going to know what a ternary operator is they likely won't right so try not to use those right okay so the good tried and true noun verb class name function name has always proven uh to work well there's going to be exceptions to that but that's typically the way the way to go i don't like to see and servicenow does this a lot like if you throw util at the end of a class theme does that give me any extra information at all as to what that thing does i i know utility methods in some some languages like java they do make sense to because they actually have a purpose because a utility method is one that doesn't have to be instantiated it's one that's already instantiated for you whenever you pull it up and that has a definition but in javascript it doesn't right and in servicenow it definitely doesn't so if you're putting manager on the end of your class name or util on the end of your class name there's probably a better way to say exactly what it's doing or if it's user util why not just call it user right because now and and by the way i understand that for purposes of not colliding with other code we do need to put prefixes on a lot of these typically we ask the customer what they want for the prefix on their on their script includes and if they don't want a prefix on their script includes i'll usually throw something out there anyway because i don't want my stuff to ever collide with what servicenow has built either okay sometimes i'll just throw gf on the front of it for glide fast so but anyway you know manager util things like that just you know try and think of better ways to name them at the end of the day because every function or every class can be looked at as a utility right it's what it's doing it's doing code code is utility so you know try and be really descriptive with that i say this is probably controversial but i don't use comments unless i absolutely have to i did see that was mentioned in chat about jsdoc and i agree with that if you're if you're adding comments to do documentation on your class and functions that is valid and you know jsdoc is great but and if the customer requires it it's great too but i also still believe that you can name your your functions and your classes in a way that tells people exactly what they're doing without having to break it out into 10 lines of js doc documentation right and the little comments where it's like hey this is doing this well if you can write a comment for that you can also just break it out into a function with a name that tells you exactly what it's doing rather than writing that that's going to make your code more concise it's going to make your code more maintainable the comment doesn't do anything for you other than add context where you could probably do it a different way which is why i say comments i do have a couple examples of comments like i said that i used in the code that i'm going to show everyone but i probably wouldn't use those real world i did them just as an example i'd probably break those out into functions that are named properly rather than doing them as as a comment okay all right so i think that's all for principles yeah okay cool so first off just for anyone who doesn't know script includes are in the platform type in script includes come in here and you get a whole library of scripts you know let's just go into one of them real quick it's a read-only one so i can't do anything with it but you can see that it's just it's a class right a class named global service catalog util and each one of these functions within it is a function that you can call on that class elsewhere in the platform i don't think we need to go any further into that that's how it's structured okay let's talk code so first off i want to show you a somewhat different way to write javascript servicenow uses the prototypal format like this i use a different format typically and i'll show you the difference in the two so service out the way servicenow does things is the prototype you know they actually have this method that they've created for creating class behind the scenes it makes it seem like it's a class there's you know javascript doesn't really have real classes javascript has fake classes because javascript is all prototype it's a prototype language it's not a object-oriented language but that's for another day so anyway this is how servicenow would structure a user class that has git by email get by full name get by last name right i like to write mine i create them as an object rather than as a prototype and what advantage this gives me is that i can have true private methods right so if i create a function here get first name from or by la full name right full name let's see return full name we'll just do a split on a space and say give me the second index okay now i could call this now and say get my full name here [Music] i don't know how i could use this this is just something i came up with on the fly anyway i could call this in another one of my functions in here right because it's private unless i return it in the return statement up here it's not public people cannot call it on on your function over here if i create that same function which you know looks slightly different but it's close let's do that real quick right so i need to do so over here this has a naming convention that that has an underscore on it but it's not it's not private the naming convention allows it to be private but i can still call it right because it's not truly private over here it's truly private so just the proof i prefer to now ajax wouldn't still need to be written this way i'm sure they could be written the other way but i just haven't put time into that because i don't need to so the ajax ones are typically still written the same way as servicenow writes no whenever i write so that's just an fyi if you see that i wanted to show you this because you're going to see my code is typically like this and i don't want to confuse anyone it's still a script included it still does the same exact thing as script include does it's just formatted a little bit differently okay close all okay so here's my library and this is the library that i built for a project for hardware asset management it it was branded like it had the prefix on all of the names but i removed them all because if this is going out online we don't want to put you know customers out there customer code out there so yeah you'll never know what customer it is so i want to talk about a couple of principles i was talking about first first off i want to talk about more generic versus less generic script includes so i'll start with the one that i kind of used as an example which is my most generic script include of all which is this glide service i use this a lot i use it i put it in most of my customer instances just as part of my code base to work on because it allows me to do glideworker calls in one line i know that glide query is out there and that's new it came out after i had built this so i got used to using this i find this to be easier it doesn't do as much as black query but it doesn't need to do as much as cloud query does all of you know does 99 of what i need to do on a glide record from this this this one class so very simple insert multiple which pulls multiple remove single single id so this pull single biases id this will single by query and update right so they're all very very simple and i'll show you how i'm using them and then i've got some private methods in here as well where i'm you know initializing or creating a glide record i'm populating a glide record with data from an object and then i'm forcing things to arrays or i'm forcing things to objects or i'm setting field values but you never see those right you never see the implementation of any of those private methods you just see the ones that are exposed publicly the ones that we showed at the top okay so just to show you kind of how that works let's go to the hardware right so hardware has some functions as well and these are things that i built that would make you act upon some sort of hardware asset record you know things that you do in workflows and things like that that you may need you know help along with so i don't want to define the assignment code for an asset in every workflow that may do an assignment so rather than doing that i define it here and then i call hardware you know new hardware assign pass in the hardware assist id and the user system id and it happens for me right so this is done in one place if logic changes or i need to you know change different values or whatever i come and add those here rather than redefining it anywhere we're using that glide service here at the top of the the script include and calling it hardware service so i know hardware service has all of these methods that we looked at before on glide service so the update insert single single id multiple and i can call those in a single line so this gets me a hardware asset but not as a glide record as an object right so this is just an object that has the property or the name of every field followed by either value or display value and so whenever i call it if i want to see where hardware acid is used here i can see i'm using it here hardware asset.installdate.value and that's getting me the install date and i know that it's always going to have a value even if that value is blank it's not going to be undefined because i'm making sure of that in the in the code for glide service right so i know what i'm always going to expect from glide service i'm sorry yeah cloud service that's right so that's an easy way to call one line glide record calls and then single line updates as well although it's not single line but you know i'm passing in an object so it it is actually single line because it's only one object but here i'm doing an update so up the way update works is i pass in an id this is id of the record and remember the service is based on the table name so these are always going to act on that one table alm hardware so update goes to pass in an id and then each of these represents a field so in on the back end in glide service if it finds the fuel doesn't exist it doesn't do anything because the field doesn't exist but all the property names match with fields that it'll get written to whenever i call these update methods so each one of these again just changes state right maintain reserve retire stock transfer on reserve i don't know if that's a word but that's that's what i called it that puts you back into available and in stock so all very very useful methods that can be used in the workflow or business rules or wherever you're going to use them throughout your implementation consumable is very similar it just has one method consumed now this is kind of an example of what i was talking about where you can break things out into different methods so consume first thing i'm doing is getting a consumable the consumable record based on a query right i want the ones that are i have an install status of available i'm in stock and available where the model id and the stock room match would have passed in once i get my consumable i then could have gone and created a bunch of spaghetti code for what i need to do with that consumable but rather i did this i broke it out into multiple functions so the first thing i need to know is hey is the requested quantity less than the available quantity so let's just call the function map rather than putting a comment there is the request quantity less if it is i'm going to update that available consumable and i'm going to insert a new consumed consumable right because consumables kind of work that way they decrement until they get to zero but if you decrement one that's in stock you need to create a new one that's assigned to the user because that's that's just how it works that's how consumables work but else if the requested quantity is not less than the available quantity i'm just going to update the new consumable okay so all of these are broken out into functions that make more sense than they would if it was just done in line in the same function and so that's what i wanted to show there could these be broken out more possibly i mean this one's probably doing more than one thing right here you know i could probably break this out more and i could definitely put a semicolon so you know there's always room for improvement i'll probably refactor this at some point just because i like refactoring okay so import sets kind of similar it does an import set loads and import sets from a source removes removes attachments from the data source then adds an attachment to the data source and processes it and i added a couple comments here just to show you what i mean the this is glidesys attachment copy i don't know right off the top of my head what that does maybe so i put a little note here that says it copies all attachments so i want to make sure copy is copy all actually so i put a little note in there because it's not my code it's a third-party code now i could have wrapped that in its own function which i kind of did here and it does say copy attachments i know but you see what i'm saying i did this because i wanted to to show you guys and then here again transform worker set background that really doesn't make a whole lot of sense to me what that's doing so i put a little note in there to say that makes the transform run in the background rather than locking things up okay so just little examples i want to show you this we're down to 13 minutes i want to i can talk i know i'm sorry but i want to show you guys the rest api one that i built here and how it works with another thing so i have a very base script or class here it's kind of like live service but it's for rest apis i've probably worked with this with a few of you might recognize it very simple it is for a basic authorization rest call and i just created a class here that has all four of the most commonly used uh rest api methods so get patch post and remove each one of those is a function that calls execute request and passes in the method as well as any information that may be needed right so get passes in the endpoint and the method but patch and post pass in payloads and then i the each of these functions calls execute request and execute request knows how to handle each one of them right so no matter what i'm always going to get an object out as a as a response it's either going to be a parse response or a parse error either way i'm getting an object that has a status and either a message or a body so i know i'm never going to get a crappy you know message from the from the wrestler i'm just going to get my own messages packaged up exactly as i would expect them so that whenever i call this i can call it in a much more structured way in a in a way where i don't have to do a bunch of spaghetti code with catch you know try catches and you know error handling and all that good stuff so yeah if there's a payload it sets the payload stringifies it and sets the payload it then executes and then parses the response or the error so that's it this is used i use this all over the place one example is in the cdw api this customer needed an integration with cdw so this and this that isn't actually the code i used for the customer i think chef built this i just adapted it so i can show you guys those things it's got one function create order right so this may you may have defined this as create order as a rest message in servicenow i feel like those records the rest message records kind of box you in because if you change them you have to change your code if you're referencing anything i just find it easier to do the rest call strictly in code and also whenever you have a rest message defined and you go from prod to test or test the prod you have to change the end point you might have to change the end point right so i like to do it in code so create order passes in our requested item that i know is the hardware requested item that we're requesting of cdw we have a basic authenticity of that basic auth is stored in a system property so we're passing that into our rest api which is the map the class i just showed you which i don't know if i showed you that all it takes in up here is a basic auth id as a parameter so pass in the basic health id we then call post with the endpoint that we've provided right here and we have a function to build our payload because putting that in here would have been giving it more than one concern right so builds a payload based on the requested item variables and things like that this could be broken out more i know for a fact but i think it's still a good example of utilizing a more general i mean more generic script include with a less generic script include okay and then i just have a few like user preference which is just doing get value set value and user preferences these you could use everywhere i know there's already apis for user preference but they differ between global and scoped and they also have one on the client side that works i think it works on portal but not outside a portal or something it's just inconsistent so i call them with this then i use the ajax call that supports that one that calls the same functions from user preference set value and get value so i always have consistency with with getting user preferences or system properties so i'll typically bring these into projects that i'm working on anytime i need to get these these pieces of information okay and then variable variable ajax is just getting variable information for some other use i can't remember exactly what i'm using it for here oh and and i do want to show i have the least generic script include right here and it's big i would definitely argue it's too big but it's also one of those things that frankenstein out right that you start building so what this is is i think of scripts as a flow right starting with the most generic being glide service it's used everywhere and then going into more less generic and this one is the most specific this has functions in it that only pertain to requested items that have to do with hardware so i have variables in here i have variable values that i need to get if you can think of having multiple items like order hardware install hardware i'm probably not a good example but order i don't know another one reclaim something like that right so you have all these things that you can do with hardware order or get back well business reason is something that they required for all of their different ones but there was different values based on what type of item it was what type of catalog item it was so what i'm doing down here for get business reason is i'm saying if it's a hardware assignment requested item then return me this variable if it's a hardware collection which is they were collecting it back then give me this variable and if it's a consumable request give me this variable right so what this is is that it channels i can call get business reason anywhere i want to call get business reason and it's going to automatically figure out for me which business reason i need and i can be confident because i know this is what i built that it's going to give me a value or or a blank string but it's going to give me the value that i need based on what the catalog item is and so rather than calling you know get business reason 4 hardware assignment or get business reason for hardware collection i could call the same function in all of those different workflows which allows me to make the workflows more generic as well right so based on if at the beginning of the workflow i collect what catalog item it is that this is related to i now can call this function get business reason one time and it's going to calculate what it needs to get because i know what item what catalog what requested item i'm passing into it hopefully that makes sense but i do this a lot with especially with large requests because it's just very very like get model with hardware there's so many ways model could be set in all the different ways that we were doing this you know all the different catalog items we had here but get model is always going to get me a model because it's based on what type of what type of item it is so not generic at all but that's okay because that's what that's his purpose it is is as general as it can be for its purpose which is serving information or serving process to a hardware requested item okay and i think that's it i have five minutes i talked all the way up to five minutes so questions questions hey yeah um hey jody so i i agree with a lot of what you have said today so you know disclaimer noted no all that kind of stuff but most of what you have said is is perfectly valid within the bounds of of you know you have an instance and you're trying to come up with a good or advise a customer on a good way to maintain that instance and the code that goes into that instance but what about you know existing instances for which we do contract work you know how do you recogni how do you recommend this specific type of organization strictly within the browns of what we are contracted to do with a particular customer particular instance as opposed to like a ground up or advisory type you know thing for the instant yeah so i probably wouldn't change my strategy too too much if it was if it's a maintenance thing and not a build from scratch but i would definitely try and get my bearing of what is already in that customer's instance because if they already have some classes that you could leverage and you don't have to create as part of your library but could bring into your library then you definitely want to do that a good example is fisfis has built a ton of stuff right like prior to us and i i know we i reuse their stuff all the time i find a method that they're doing i make sure that first off i make sure that method is doing exactly what i want it to do but then a lot of times i'll encapsulate that method into my own method because i just want to remain consistent with how i'm calling things but ultimately still using the code that already exists in the in their their code base so i would just say be very cautious before you create things make sure you've you've vetted everything that's out there and there's not something already out there doing what you need it to do and if it is and it does and it's not exactly as you want it you know i i'd make the argument let's fix it and and get it exactly as we want it and and then adopt it into our our code base is it is there any guideline that you have or or what not for how much time we're allowed to allocate towards examining what they have i mean because i mean any time we spend we have to build hours for it so you know yeah and it's not especially if it's not something that we're actually under contract to build you know sure you know what i mean and if that's the case so if going out and searching for you know five or ten minutes to try and find something that you know is going to take you know hours to build it's worthwhile in my opinion i don't have guidance on exactly what that may be i will typically when i know what my code is doing like i know the fields that it's updating things like that i don't know the tables it's updating go search through all the script includes through the script field and actually search for that field or search for that table name and see what comes back see if and you know obviously i'm not going to look too far into the stuff that servicenow created because i typically know the lay of all of that already but look at the stuff that that customer has created or other consultants have created prior to you and just do a little digging i wouldn't put too much time into it though i mean if you know if you let's say you already have a code base built out i would probably if it's something very complex i'd probably just use my code at that point because you're right it could be prohibitive actually doing that search i think it's a case-by-case basis though exactly and that's why i was asking you know for the benefit of the recording and everybody else was listening because i was thinking the same thing you know ultimately yes if we're managing an instance if you're working for a customer full-time then all this matters but for our work in particular we're on a contract we have limited hours to accomplish the mission you're going to have to weigh it every single time is it worth it to encapsulate everything we do into a set library that is specific to what we were contracted to do just because it's more time efficient or are we is this one of those contracts where it's we're at the mercy of the customer it's whatever they want us to do and so really it's in the customer's best interest for us to learn their code base and build within it or expand it you know as needed especially when they have a good process in place right absolutely yes i agree 100 100 it is always a case-by-case basis this is very general yeah awesome question though thanks judy time's up but anybody else have anything and you guys please reach out to me one-on-one or in a group chat or whatever if you guys have questions that come up i i appreciate everyone attending go ahead i was curious if you are calling your script include the same manner as you would with a prototypal yes exactly the same new name of the the script includes dot function name yep thank you yeah no problem no problem okay excellent thanks everyone for your time i know everyone has meetings to get to so everyone have a great weekend if i don't talk to you and thanks thanks again yeah definitely thanks [Music] you
https://www.youtube.com/watch?v=xlzq_v1TRxc